我从LINQ查询得到的结果为IEnumerable<T>
我希望根据LINQ
的结果创建CSV文件我从以下查询中获得结果
var r = from table in myDataTable.AsEnumerable()
orderby table.Field<string>(para1)
group table by new { Name = table[para1], Y = table[para2] }
into ResultTable
select new
{
Name = ResultTable.Key,
Count = ResultTable.Count()
};
答案 0 :(得分:17)
检查
public static class LinqToCSV
{
public static string ToCsv<T>(this IEnumerable<T> items)
where T : class
{
var csvBuilder = new StringBuilder();
var properties = typeof(T).GetProperties();
foreach (T item in items)
{
string line = string.Join(",",properties.Select(p => p.GetValue(item, null).ToCsvValue()).ToArray());
csvBuilder.AppendLine(line);
}
return csvBuilder.ToString();
}
private static string ToCsvValue<T>(this T item)
{
if(item == null) return "\"\"";
if (item is string)
{
return string.Format("\"{0}\"", item.ToString().Replace("\"", "\\\""));
}
double dummy;
if (double.TryParse(item.ToString(), out dummy))
{
return string.Format("{0}", item);
}
return string.Format("\"{0}\"", item);
}
}
答案 1 :(得分:6)
IEnumerable<string> lines = r.Select(x => String.Format("{0},{1}", r.Name, r.Count));
System.IO.File.WriteAllLines(path, lines);
将产生:
name1,count1
name2,count2
...
答案 2 :(得分:2)
对于Linq2CSV来说,这是在尖叫:
http://www.codeproject.com/KB/linq/LINQtoCSV.aspx
也可以在nuget上找到:
http://nuget.org/List/Packages/LinqToCsv
优秀的图书馆,真的值得推荐。
答案 3 :(得分:2)
不清楚你真正想要的是什么,但这可以是一个解决方案public void Read(){
var r = from table in myDataTable.AsEnumerable()
orderby table.Field<string>(para1)
group table by new { Name = table[para1], Y = table[para2] }
into ResultTable
select new NameCount()
{
Name = ResultTable.Key,
Count = ResultTable.Count()
}.ToString();
//Write all r to a File
}
public class NameCount
{
public string Name { get; set; }
public int Count { get; set; }
public string ToString()
{
return string.Format("{0},{1}\r\n", Name, Count);
}
}
答案 4 :(得分:1)
这是我用于任何IEnumerable的基本解决方案:
using System.Reflection;
using System.Text;
//***
public void ToCSV<T>(IEnumerable<T> items, string filePath)
{
var dataTable = new DataTable(typeof(T).Name);
PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in props)
dataTable.Columns.Add(prop.Name, prop.PropertyType);
foreach (var item in items)
{
var values = new object[props.Length];
for (var i = 0; i < props.Length; i++)
{
values[i] = props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
StringBuilder fileContent = new StringBuilder();
foreach (var col in dataTable.Columns)
fileContent.Append(col.ToString() + ",");
fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
foreach (DataRow dr in dataTable.Rows)
{
foreach (var column in dr.ItemArray)
fileContent.Append("\"" + column.ToString() + "\",");
fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
}
//good place to validate File.Exist or catch exceptions
System.IO.File.WriteAllText(filePath, fileContent.ToString());
}
答案 5 :(得分:0)
我从你的问题中假设你想要一个 Generic 方法来做这件事,不管T是什么?
像
这样的东西public void ToCSV<T>(IEnumerable<T>, TextWriter writer) . . .
您无法克服的问题是,T
是一个复杂的类型,逗号分隔T
的每个元素,您需要了解T
的内部,或{ {1}}需要知道如何将它自己写为CSV行,这意味着您需要一个ICSVRow接口,并且您需要将T约束到实现ICSVRow的对象。这也意味着这对匿名类型不起作用。
任何问题都只是喊出来。