有没有一个快速的方法来转换一个实体到.csv文件?

uqdfh47h  于 2023-06-03  发布在  其他
关注(0)|答案(4)|浏览(185)

目前,我有:

string outputRow = string.Empty;
        foreach (var entityObject in entityObjects)
        {
            outputRow = entityObject.field1 + "," + entityObject.Field2  etc....
        }

我对实体框架还是新手,有更快的方法吗?

qoefvg9y

qoefvg9y1#

示例代码显示了一种简单而强大的方法来实现您想要的功能,而无需硬编码属性名称(使用反射):

/// <summary>
 /// Creates a comma delimeted string of all the objects property values names.
 /// </summary>
 /// <param name="obj">object.</param>
 /// <returns>string.</returns>
 public static string ObjectToCsvData(object obj)
 {
     if (obj == null)
     {
         throw new ArgumentNullException("obj", "Value can not be null or Nothing!");
     }
  
     StringBuilder sb = new StringBuilder();
     Type t = obj.GetType();
     PropertyInfo[] pi = t.GetProperties();
  
     for (int index = 0; index < pi.Length; index++)
     {
         sb.Append(pi[index].GetValue(obj, null));
  
         if (index < pi.Length - 1)
         {
            sb.Append(",");
         }
     }
  
     return sb.ToString();
 }

更多关于此:
Objects to CSV
How can i convert a list of objects to csv
Are there any CSV readers/writer lib’s in c#
Writing a CSV file in .net
LINQ to CSV : Getting data the way you want
LINQ to CSV library

lnxxn5zx

lnxxn5zx2#

我采纳了Leniel的建议,并将其 Package 在一个功能齐全的“writer”中,该“writer”还允许您过滤想要写入的属性。下面是您的使用代码:

public class CsvFileWriter
{
    public static void WriteToFile<T>(string filePath, List<T> objs, string[] propertyNames)
    {
        var builder = new StringBuilder();
        var propertyInfos = RelevantPropertyInfos<T>(propertyNames);
        foreach (var obj in objs)
            builder.AppendLine(CsvDataFor(obj, propertyInfos));

        File.WriteAllText(filePath, builder.ToString());
    }

    public static void WriteToFileSingleFieldOneLine<T>(string filePath, List<T> objs, string propertyName)
    {
        var builder = new StringBuilder();
        var propertyInfos = RelevantPropertyInfos<T>(new[] { propertyName });
        for (var i = 0; i < objs.Count; i++)
        {
            builder.Append(CsvDataFor(objs[i], propertyInfos));

            if (i < objs.Count - 1)
                builder.Append(",");
        }

        File.WriteAllText(filePath, builder.ToString());
    }

    private static List<PropertyInfo> RelevantPropertyInfos<T>(IEnumerable<string> propertyNames)
    {
        var propertyInfos = typeof(T).GetProperties().Where(p => propertyNames.Contains(p.Name)).ToDictionary(pi => pi.Name, pi => pi);
        return (from propertyName in propertyNames where propertyInfos.ContainsKey(propertyName) select propertyInfos[propertyName]).ToList();
    }

    private static string CsvDataFor(object obj, IList<PropertyInfo> propertyInfos)
    {
        if (obj == null)
            return "";

        var builder = new StringBuilder();

        for (var i = 0; i < propertyInfos.Count; i++)
        {
            builder.Append(propertyInfos[i].GetValue(obj, null));

            if (i < propertyInfos.Count - 1)
                builder.Append(",");
        }

        return builder.ToString();
    }
}
5f0d552i

5f0d552i3#

string csv = "";
//get property names from the first object using reflection    
IEnumerable<PropertyInfo> props = entityObjects.First().GetType().GetProperties();

//header 
csv += String.Join(", ",props.Select(prop => prop.Name)) + "\r\n";

//rows
foreach(var entityObject in entityObjects) 
{ 
    csv += String.Join(", ", props.Select(
        prop => ( prop.GetValue(entityObject, null) ?? "" ).ToString() 
    ) )
    + "\r\n";
}
  • 对于很多实体使用StringBuilder会更好
  • 代码不检查entityObjects何时为空
v09wglhw

v09wglhw4#

基于@mBria的代码,我更新了它,以便您可以使用点表示法提供相关的表属性:

public class CsvFileWriter
{
    public static void WriteToFile<T>(string filePath, List<T> objs, string[] propertyNames)
    {
        var builder = new StringBuilder();
        var propertyInfos = RelevantPropertyInfos<T>(propertyNames);
        foreach (var obj in objs)
            builder.AppendLine(CsvDataFor(obj, propertyInfos));

        File.WriteAllText(filePath, builder.ToString());
    }

    public static void WriteToFileSingleFieldOneLine<T>(string filePath, List<T> objs, string propertyName)
    {
        var builder = new StringBuilder();
        var propertyInfos = RelevantPropertyInfos<T>(new[] { propertyName });
        for (var i = 0; i < objs.Count; i++)
        {
            builder.Append(CsvDataFor(objs[i], propertyInfos));

            if (i < objs.Count - 1)
                builder.Append(",");
        }

        File.WriteAllText(filePath, builder.ToString());
    }
        public static string GetCSVData<T>(List<T> objs, string[] propertyNames, string[] renameHeaders)
        {
            var propertyInfos = RelevantPropertyInfos<T>(propertyNames);
            var builder = new StringBuilder();

            if (renameHeaders != null && renameHeaders.Count() > 0)
                builder.AppendLine("\"" + String.Join("\",\"", renameHeaders.Select(i => i.Replace("\"", "'"))) + "\"");
            else
                builder.AppendLine(String.Join(",", propertyInfos.Select(i => i.Name).ToList()));

            foreach (var obj in objs)
                builder.AppendLine(CsvDataFor(obj, propertyInfos));

            return builder.ToString();
        }
        
        private static List<PropertyInfo> RelevantPropertyInfos<T>(IEnumerable<string> propertyNames)
        {
            var propertyInfos = typeof(T).GetProperties().Where(p => propertyNames.Contains(p.Name)).ToDictionary(pi => pi.Name, pi => pi);
            propertyInfos.Remove("EntityAspect");

            // Adding related objects
            foreach (var property in typeof(T).GetProperties())
            {
                if (property.PropertyType.Namespace == "System.Collections.Generic") // if property is a collection
                {
                    var subType = property.PropertyType.GenericTypeArguments[0]; // Get the type of items in collection
                    var subProperties = subType.GetProperties().Where(p => propertyNames.Contains($"{property.Name}.{p.Name}")); // Get properties of related object

                    foreach (var subProperty in subProperties)
                    {
                        propertyInfos.Add($"{property.Name}.{subProperty.Name}", subProperty); // Add subproperties to propertyInfos
                    }
                }
                else if (!property.PropertyType.Namespace.StartsWith("System")) // if property is an object
                {
                    var subProperties = property.PropertyType.GetProperties().Where(p => propertyNames.Contains($"{property.Name}.{p.Name}")); // Get properties of related object

                    foreach (var subProperty in subProperties)
                    {
                        propertyInfos.Add($"{property.Name}.{subProperty.Name}", subProperty); // Add subproperties to propertyInfos
                    }
                }
            }

            return (from propertyName in propertyNames where propertyInfos.ContainsKey(propertyName) select propertyInfos[propertyName]).ToList();
        }

        private static string CsvDataFor<T>(T obj, List<PropertyInfo> propertyInfos)
        {
            var values = new List<string>();

            foreach (var propertyInfo in propertyInfos)
            {
                try
                {
                    // Check if it's a nested property
                    if (propertyInfo.ReflectedType.Name != obj.GetType().Name)
                    {
                        var property = typeof(T).GetProperty(propertyInfo.ReflectedType.Name);

                        if (property != null)
                        {
                            var subProperty = property.PropertyType.GetProperty(propertyInfo.Name);

                            if (subProperty != null)
                            {
                                if (property.PropertyType.Namespace == "System.Collections.Generic") // if it's a collection
                                {
                                    var collection = property.GetValue(obj) as IEnumerable;

                                    if (collection != null)
                                    {
                                        values.Add(String.Join(";", from object item in collection select subProperty.GetValue(item)?.ToString()));
                                    }
                                    else
                                    {
                                        values.Add(""); // Add empty value if collection is null
                                    }
                                }
                                else // if it's a single object
                                {
                                    var relatedObject = property.GetValue(obj);

                                    if (relatedObject != null)
                                    {
                                        values.Add(subProperty.GetValue(relatedObject)?.ToString());
                                    }
                                    else
                                    {
                                        values.Add(""); // Add empty value if related object is null
                                    }
                                }
                            }
                            else
                            {
                                values.Add(""); // Add empty value if subProperty not found
                            }
                        }
                        else
                        {
                            values.Add(""); // Add empty value if property not found
                        }
                    }
                    else
                    {
                        var value = propertyInfo.GetValue(obj);
                        values.Add(value == null ? "" : value.ToString());
                    }
                }
                catch (Exception ex)
                {
                    // Handle any error that occurred during getting the value.
                    // This block will catch any unhandled exceptions and allow the loop to continue with the next property.
                    // Add error handling code here as needed.

                    values.Add(""); // Add empty value in case of error
                }
            }

            //Join the string representations of the values with a comma and return the result.
            return string.Join(",", values);
        }
}

相关问题