实体框架6:有没有办法在不保存内存中的每一行的情况下迭代表

Myt*_*dia 8 entity-framework entity-framework-6 entity-framework-6.1

我希望能够遍历实体表中的每一行而不保留内存中的每一行.这是一个只读操作,每行可以在处理后丢弃.

如果有一种方法可以在处理后丢弃该行,那就没问题了.我知道这可以使用DataReader(超出EF的范围)来实现,但它可以在EF中实现吗?

或者有没有办法从EF中获取DataReader而不直接使用SQL?

更详细的例子:

使用EF我可以编码:

foreach (Quote in context.Quotes)
   sw.WriteLine(sw.QuoteId.ToString()+","+sw.Quotation);
Run Code Online (Sandbox Code Playgroud)

但要使用DataReader实现相同的结果,我需要编写代码:

// get the connection to the database
SqlConnection connection = context.Database.Connection as SqlConnection;

// open a new connection to the database
connection.Open();

// get a DataReader for our table
SqlCommand command = new SqlCommand(context.Quotes.ToString(), connection);
SqlDataReader dr = command.ExecuteReader();

// get a recipient for our database fields
object[] L = new object[dr.FieldCount];

while (dr.Read())
{
    dr.GetValues(L);
    sw.WriteLine(((int)L[0]).ToString() + "," + (string)L[1]);
}
Run Code Online (Sandbox Code Playgroud)

区别在于前者耗尽内存(因为它在客户端内存中拉入整个表),后者运行完成(并且速度更快),因为它在任何时候都只在内存中保留一行.

但同样重要的是后一个例子失去了EF的强类型,如果数据库发生变化,就会引入错误.

因此,我的问题是:我们能否在EF中返回强类型行获得类似的结果?

Yul*_*dra 5

根据你上次的评论,我仍然感到困惑.看看以下两个代码.

EF

using (var ctx = new AppContext())
{
    foreach (var order in ctx.Orders)
    {
        Console.WriteLine(order.Date);
    }
}
Run Code Online (Sandbox Code Playgroud)

EF Profiler

数据阅读器

var constr = ConfigurationManager.ConnectionStrings["AppContext"].ConnectionString;
using (var con = new SqlConnection(constr))
{
    con.Open();    
    var cmd = new SqlCommand("select * from dbo.Orders", con);
    var reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        Console.WriteLine(reader["Date"]);
    }
}
Run Code Online (Sandbox Code Playgroud)

数据读取器分析器

尽管EF初始查询很少,但它们都执行类似的查询,可以从profiler中看到.

  • 好.理解混乱.我将修改问题以提供更多细节.一句话:我不担心从数据库中提取行.如您所说,在这两种情况下,将使用相同的DB成本获取相同数量的行.*但是当表是5,000,000行时(在我的简单示例中),数据库可以在几秒钟内遍历,但是我的应用程序内存不足,试图在内存中保存大约5-10GB的数据.我只需要在本地一次保持一行,而不是整个表. (3认同)
  • 问题不在于EF提取的记录数量:我希望它最终获取表中的每条记录.问题是我的客户端程序一次只需要一张记录表; 它不需要保留客户端程序中的其他5,000,000条记录.请参阅修订后的问题中的代码.当表是5,000条记录时(在遍历列表后立即释放内存),没有问题; 问题是当表太大而不能立即适应客户端内存时.更糟糕 - 这只是TEST数据,数据库的大小将会大幅增长. (2认同)