仅将DB Entity对象中的某些列转换为逗号分隔列表

时间:2017-03-02 20:10:37

标签: c# arrays entity-framework linq

我有一张表(让我们称之为Reg),如下所示:

RegId    FirstName    LastName    City         CreatedBy    DateCreated
------------------------------------------------------------------------
  1       John          Doe        New York       123          1/1/2017
  2       Jane          Doe        Miami          298          2/2/2017

我只需要将此表中的一些列放入逗号分隔的平面文件中。我不确定只选择某些列的最有效方法,将它们放入List<String>String[]数组中,以便可以将其写入平面文件。

我需要每一行,所以我可以从这里开始:

var regs = Context.Reg.ToList();

regs现在每行都有一列。但是,让我们说我只需要:

FirtName, LastName, City

如何最好地提取这些列并将它们放入List<String>String[]数组中。实际上,将不仅仅有三列。我只是想为了这个问题而保持简单。我添加这个是因为我而不是创建一个单独的对象,我只选择我想要的列。

修改

就这样我才有意义,我想要的是:

John,Doe,New York
Jane,Doe,Miami

3 个答案:

答案 0 :(得分:3)

如果您正在使用更大的表格,如果您只是检索可能导致OutOfMemoryException

的所有内容,那么这些事情就非常重要
  • 使用AsNoTracking(),这将确保实例不会保持与DbContext的连接
    • 如果使用匿名投影(即选择表达式),AsNoTracking()可以被忽略,因为它没有任何意义,因为上下文不会跟踪投影。
  • 直接从DbSet使用循环(或IQueryable如果你想稍后添加过滤也可以),这将确保在你写作时可以释放托管内存记录到流中。
  • 将生成的字符串写入循环内的Stream,不要在内存中聚合字符串。

对于行级别字符串连接,请使用string.Join并传入要包含的属性。

代码

using(var Context = new YourDbContext())
{
    // the Select expression is optional, if you have many properties on the model that are not used it can 
    // increase efficiency to only pull back what you are going to write to the stream
    // If using the Select you can safely omit AsNoTracking
    foreach(var record in Context.Reg.AsNoTracking().Select(x => new {x.FirstName, x.LastName, x.City /* etc */ }))
    {
        var stringToWrite = string.Join(",", record.FirstName, record.LastName, record.City /* etc. */);
        // write the string to a stream or output
    }
}

答案 1 :(得分:2)

编辑:在Context.Reg之后添加了ToList(),因为EntityFramework不支持String.Join,所以我们必须先将数据拉入内存,因为我们可以选择。

查询语法:

var list = (from col in Context.Reg.ToList()
            select String.Join(",", x.FirstName, x.LastName, x.City/*additonal columns here*/))
            .ToList();

流利语法:

var list = Context.Reg.ToList()
               .Select(x => String.Join(",", x.FirstName, x.LastName, x.City/*additonal columns here*/))
               .ToList();

答案 2 :(得分:2)

如果您事先了解所需的列,则可以使用此模式:

context.Regs
       .Select(r => new List<string> { r.FirstName, r.LastName, r.City })
       .AsEnumerable().Select(list => string.Join(",", list))

这不需要中间类,并且(因为AsEnumerable())它不能直接在LINQ-to-Entities查询中使用string.Join,这不是&#39 ;支持。

尽管这是编写查询的一种方便且非常简洁的方法,但生成的SQL并不太优雅。您必须测试它是否能够充分发挥作用。

您也可以使用r.DateCreated.ToString()等。{Entity Framework 6.1.1(或其附近)支持大多数原始类型ToString。当然,这取决于数据库文化和设置将返回哪些字符串。