目前,我有:
string outputRow = string.Empty;
foreach (var entityObject in entityObjects)
{
outputRow = entityObject.field1 + "," + entityObject.Field2 etc....
}
我对Entity Framework还很陌生,有没有更快的方法?
目前,我有:
string outputRow = string.Empty;
foreach (var entityObject in entityObjects)
{
outputRow = entityObject.field1 + "," + entityObject.Field2 etc....
}
我对Entity Framework还很陌生,有没有更快的方法?
以下是一段示例代码,展示了一种简单而强大的方法来实现您想要的功能,无需硬编码属性名称(使用反射):
/// <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();
}
更多相关内容:
我采纳了Leniel的建议,并将其包装成一个功能齐全的“写入器”,它还允许您过滤要写入的属性。以下是您可以使用的代码:
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();
}
}
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";
}
在 @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);
}
}