【问题标题】:SQL Table to CSV using LINQ使用 LINQ 将 SQL 表转换为 CSV
【发布时间】:2012-07-08 12:43:08
【问题描述】:

我正在尝试将表格转换为逗号分隔的 CSV 文件。我目前是这样实现的:

var csv = new StringBuilder("id,Name,Address,City,State\n");
var delimiter = ",";
var newline = "\n";

using (var db = MyDatabase())
{
     var query = from c in db.Customers select c;
     foreach(var q in query)
         csv.Append(q.id).Append(delimiter)
             .Append(q.name).Append(delimiter)
             .Append(q.address).Append(delimiter)
             .Append(q.city).Append(delimiter)
             .Append(q.state).Append(newline);
}

这会创建一个 csv 罚款。但我的问题是,有没有一种更简化的方法可以实现这一点而不单独指定每一列?在某些情况下,我想做一个全选,但是表格有很多列,这似乎有点笨拙。

【问题讨论】:

  • 当您的 CSV 文件到达 123 Main St., Suite 200 这样的地址时会发生什么情况?制作 CSV 文件比附加一些原始数据和逗号更重要。不要重新发明轮子。 .Net 有许多 CSV 类。
  • 例如,CsvHelper 和 FileHelpers。见stackoverflow.com/questions/1941392/…
  • 好点,但在这种情况下,我所做的只是将使用 sql 脚本完成的旧手动方式自动化,因此字段中没有逗号。这些“众多” csv 类的任何示例?谢谢。
  • 这是我写的一个辅助类。它可能对您的任务有所帮助。 Reading and Writing CSV Files in C#.

标签: c# linq-to-sql csv


【解决方案1】:

我使用这个代码:

string delimiter = "|";
string newLine = Environment.NewLine;

using (mCustDataContext = new CustDataContext()) {
    var props = typeof(Customer).GetProperties();

    StringBuilder headers = new StringBuilder(string.Join(delimiter, props.Select(c => c.Name).ToArray()) + newLine);

    Func<Customer, string> myFunc = c => 
         string.Join(delimiter, props.Select(b => b.GetValue(c,null))) + newLine;

    var query = mCustDataContext.Customers.Select(myFunc);

    foreach(var q in query)
        headers.Append(q);

    File.WriteAllText(yourFileName, headers.ToString(), mEncoding);
}

【讨论】:

    【解决方案2】:

    您想要实现的最短路径可能是:

    var props = typeof(Customer).GetProperties(
              BindingFlags.Instance|BindingFlags.Public
          );
    
    StringBuilder result = new StringBuilder(
             (
                 from prop in props select prop.Name
             ).Join(',') + "\n"
         );
    
    Function<string,Customer> project = ( 
       Customer c => (
               from prop in props 
               select prop.GetValue(c).ToString()
           ).Join(",")+"\n";
    )
    
    using (var db = MyDatabase())
    {
        var query = from c in db.Customers select project(c);
        foreach (var res in query) {
            result.append(res);
        }
    }
    

    您可以轻松地使其更通用,但是您需要缓存反射的 PropertyInfos 以避免在类型上大量使用反射。

    警告:您应该正确转义属性值,因为换行符、逗号、引号等可能会破坏您的 CSV 文件。更好的是,使用已经解决的库 编写正确的 CSV 文件的问题。

    【讨论】:

      【解决方案3】:

      为了在不指定要写入 CSV 的每个属性的情况下执行此操作,您需要使用反射。这是一个如何做到这一点的基本示例:

      List<Customer> query = from c in db.Customers select c;
              foreach (var q in query)
              {
                  Type type = typeof(Customer);
                  PropertyInfo[] properties = type.GetProperties();
                  foreach (PropertyInfo property in properties)
                  {
                      string value = property.GetValue(type, null) != null
                          ? property.GetValue(type, null).ToString() 
                          : string.Empty; // or whatever you want the default text to be
                      csv.Append(q.id).Append(delimiter);
                  }
              }
      

      这将遍历查询中的每个客户,然后遍历客户中的每个属性并写入值。这是假设您希望将 Customer 的每个属性写入 CSV 文件。这至少应该让你知道如何去做你想要完成的事情。

      【讨论】:

      • 你可以使用 .net csv 辅助类,但仍然使用反射的功能
      • Umm.. 一个链接会有所帮助——我得到了 filehepers,但我不想使用它。我需要再次将 csv 加载到 linq2sql 数据上下文中而不创建新类。拥有 300 个属性
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多