2011-06-01 57 views
9

我正在從LINQ查詢類型的VAR IEnumerable<T>的IEnumerable <T>到CSV文件

我想從結果從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

T是什麼類型? – 2011-06-01 10:26:51

+0

這個問題有點不清楚,已經有2票投票結束爲「不是真正的問題」。請參閱http://tinyurl.com/so-hints,看看你是否可以改善這個問題。 – 2011-06-01 10:27:26

回答

13

入住這

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); 
     } 
    } 

在全碼:Scott Hanselman's ComputerZen Blog - From Linq To CSV

+0

感謝您的解決方案 – usr021986 2011-06-02 05:29:48

+0

@ScottHanselman該代碼有一個錯誤。它嘗試使用'/「''在字符串中引用引號,這是不正確的。對於CSV,使用雙引號可以引用引號。https://en.wikipedia.org/wiki/Comma-separated_values – MgSam 2018-01-18 16:09:27

5
IEnumerable<string> lines = r.Select(x => String.Format("{0},{1}", r.Name, r.Count)); 
System.IO.File.WriteAllLines(path, lines); 

會產生:

name1,count1 
name2,count2 
... 
+0

我不明白你的觀點。我想從IEnumrable的結果創建csv文件 usr021986 2011-06-01 10:27:56

+0

@abatishchev:這將不起作用:'IEnumerable '不能轉換爲'IEnumerable '。 – 2011-06-01 10:28:22

+0

@Daniel:當然,這是一個錯字,我的意思是'IEnumerable ',但是如果OP想'IEnumerable '那麼他的問題就沒有意義了。 – abatishchev 2011-06-01 10:40:32

0

我從你的問題中假設你想要一個通用這樣做的方法,不管T是什麼?

喜歡的東西

public void ToCSV<T>(IEnumerable<T>, TextWriter writer) . . . 

什麼克服不了的問題,是T是一個複雜的類型,以逗號你需要了解的T的內部,或T需要的T每個元素分開知道如何將它自己寫成CSV行,這意味着您需要一個ICSVRow接口,並且您需要將T約束爲實現ICSVRow的對象。這也意味着這不適用於匿名類型。

任何問題只是喊。

+0

是的,我想通用的方法,無論T – usr021986 2011-06-01 11:30:18

+0

@ user373083:然後,你需要使用反射來獲得枚舉類型的屬性,這可以是蠕蟲的罐頭,你可能需要非常嚴格瞭解ToCSV將與T做什麼,否則它將變成一場噩夢。你是否擅長反思,或者我應該發佈一些_how以開始_代碼? – 2011-06-01 11:48:31

2

它不清楚你真的想要什麼,但是這可能是一個解決方案 公共無效閱讀() {

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); 
    } 
} 
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());    
    } 
+0

如果你是不會去處理這個異常,一開始就沒有意識到它的存在,例外情況應該被捕獲到它們可以被處理的地方 – mason 2017-01-17 18:39:47

+0

當然,我刪除了我正在使用的部分代碼,並忘記刪除這部分代碼。 – 2017-01-17 19:07:56

相關問題