2013-04-23 106 views
1

我使用最新的实体框架与DBContext。我有一个结果集,我想要转换为逗号分隔值。我在VB DataTable to CSV extraction中用DataTables做了类似的事情。我有QuoteName方法工作。我也得到了使用foreach工作的GetCSV方法的派生。问题在于它比DataTable的可比较代码慢得多。所以我希望有人会有一些建议。.Net Entity Framework to CSV

public static string GetCSV(this IQueryable entity) 
    { 
     if (entity == null) 
     { 
      throw new ArgumentNullException("entity"); 
     } 
     Type T = entity.ElementType; 
     var props = T.GetProperties(BindingFlags.Public | BindingFlags.Instance); 
     string s = string.Empty; 
     int iCols = props.Count(); 

     try 
     { 
      s += string.Join(",", (from int ii in Enumerable.Range(0, iCols) 
            select props[ii].Name.QuoteName("[]")).ToArray()); 
      s += Environment.NewLine; 
      foreach (var dr in entity) 
      { 
       s += string.Join(",", (from int ii in Enumerable.Range(0, iCols) 
             select 
              props[ii].GetValue(dr) 
                .ToString() 
                .QuoteName("\"\"", ",")).ToArray()); 
       s += Environment.NewLine; 
      } 
      s = s.TrimEnd(new char[] { (char)0x0A, (char)0x0D }); 
     } 
     catch (Exception) 
     { 

      throw; 
     } 
     return s; 
    } 
+0

嗨,我试图实现这一点,但编译器不能识别Quotename函数,我该如何做到这一点? – 2016-03-05 10:10:05

回答

2

不要使用字符串来创建您的文件。尝试使用StringBuilder类(http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx

字符串是不可变的对象 - 也就是说,一旦字符串被创建,它就不能被改变。每次你改变一个字符串(比如连接它)时,你实际上是在创建一个全新的字符串。在这里使用字符串效率很低。

相反,创建一个StringBuilder对象:

StringBuilder builder = new StringBuilder(); 

builder.Append("my data"); 

最后,只需调用

builder.ToString(); 
0

使用的一个例子,我得到了我对这个小兄弟一些帮助。他说也使用StringBuilder。

这是代码答案:

/// <summary> 
    /// Quotes a string using the following rules: 
    /// <list> 
    /// <listheader>Rules</listheader> 
    /// <item>if the string is not quoted and the string contains the separator string</item> 
    /// <item>if the string is not quoted and the string begins or ends with a space</item> 
    /// <item>if the string is not quoted and the string contains CrLf</item> 
    /// </list> 
    /// </summary> 
    /// <param name="s">String to be quoted</param> 
    /// <param name="quote"> 
    /// <list> 
    /// <listheader>quote characters</listheader> 
    /// <item>if len = 0 then double quotes assumed</item> 
    /// <item>if len = 1 then quote string is doubled for left and right quote characters</item> 
    /// <item>else first character is left quote, second character is right quote</item> 
    /// </list> 
    /// </param> 
    /// <param name="sep">separator string to check against</param> 
    /// <returns></returns> 
    /// <remarks></remarks> 
    public static string QuoteName(this string s, string quote = null, string sep = ",") 
    { 
     quote = quote == null ? "" : quote; 
     switch (quote.Length) 
     { 
      case 0: 
       quote = "\"\""; 
       break; 
      case 1: 
       quote += quote; 
       break; 
     } 
     // Fields with embedded sep are quoted 
     if ((!s.StartsWith(quote.Substring(0, 1))) && (!s.EndsWith(quote.Substring(1, 1)))) 
      if (s.Contains(sep)) 
       s = quote.Substring(0, 1) + s + quote.Substring(1, 1); 
     // Fields with leading or trailing blanks are quoted 
     if ((!s.StartsWith(quote.Substring(0, 1))) && (!s.EndsWith(quote.Substring(1, 1)))) 
      if (s.StartsWith(" ") || s.EndsWith(" ")) 
       s = quote.Substring(0, 1) + s + quote.Substring(1, 1); 
     // Fields with embedded CrLF are quoted 
     if ((!s.StartsWith(quote.Substring(0, 1))) && (!s.EndsWith(quote.Substring(1, 1)))) 
      if (s.Contains(System.Environment.NewLine)) 
       s = quote.Substring(0, 1) + s + quote.Substring(1, 1); 
     return s; 
    } 

    public static string GetCSV(this IQueryable entity) 
    { 
     if (entity == null) 
     { 
      throw new ArgumentNullException("entity"); 
     } 
     Type T = entity.ElementType; 
     var props = T.GetProperties(BindingFlags.Public | BindingFlags.Instance); 
     var sb = new StringBuilder(); 
     int iCols = props.Count(); 

     try 
     { 
      sb.Append(string.Join(",", Enumerable.Range(0, iCols).Cast<int>(). 
       Select(ii => props[ii].Name.QuoteName("[]")).ToArray())); 

      foreach (var dr in entity) 
      { 
       sb.AppendLine(); 
       sb.Append(string.Join(",", Enumerable.Range(0, iCols).Cast<int>(). 
        Select(ii => props[ii].GetValue(dr). 
         ToString().QuoteName("\"\"", ",")).ToArray())); 
      } 
     } 
     catch (Exception ex) 
     { 

      throw; 
     } 
     return sb.ToString(); 
    } 
} 

我希望这有助于别人。