【问题标题】:.Net Entity Framework to CSV.Net 实体框架到 CSV
【发布时间】:2013-04-17 04:26:29
【问题描述】:

我正在使用最新的实体框架和 DBContext。我有一个要转换为逗号分隔值的结果集。我在 VB DataTable to CSV extraction 中使用 DataTables 做了类似的事情。我有 QuoteName 方法工作。我还得到了使用 foreach 工作的 GetCSV 方法的衍生物。问题是它比 DataTable 的可比较代码慢很多。所以我希望有人能提出一些建议。

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

【问题讨论】:

  • 您好,我正在尝试实现这个,但是编译器无法识别 Quotename 函数,我该如何实现呢?

标签: c# linq entity-framework-5 export-to-csv


【解决方案1】:

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

字符串是不可变的对象——也就是说,一旦创建了字符串,就无法更改。每次更改字符串(例如连接它)时,实际上都是在创建一个全新的字符串。在这里使用字符串是非常低效的。

相反,创建一个 stringbuilder 对象:

StringBuilder builder = new StringBuilder();

builder.Append("my data");

最后,只需调用

builder.ToString();

【讨论】:

    【解决方案2】:

    查看 nuget 包 CsvHelper (http://nuget.org/packages/CsvHelper/)。

    这是https://github.com/JoshClose/CsvHelper/wiki/Basics的用法示例

    using (var csv = new CsvWriter( new StreamWriter( "Actors.csv" ) )) 
    {
        csv.WriteRecords( actorsList );
    }
    

    【讨论】:

      【解决方案3】:

      在这方面我得到了我弟弟的一些帮助。他说也要使用 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();
          }
      }
      

      我希望这对其他人有帮助。

      【讨论】:

        猜你喜欢
        • 2010-10-24
        • 2014-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-11
        • 2011-03-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多