你能使用Linq-to-SQL获得类似DataReader的流媒体吗?

mat*_*mc3 4 c# linq-to-sql

我已经使用Linq-to-SQL很长一段时间了,效果很好.但是,最近我一直在尝试使用它来提取大量数据并且遇到了一些问题.(当然,我理解L2S可能不是这种特殊处理的正确工具,但这就是为什么我在试验 - 找到它的极限.)

这是一个代码示例:

var buf = new StringBuilder();
var dc = new DataContext(AppSettings.ConnectionString);
var records = from a in dc.GetTable<MyReallyBigTable>() where a.State == "OH" select a;
var i = 0;
foreach (var record in records) {
   buf.AppendLine(record.ID.ToString());
   i += 1;
   if (i > 3) {
      break; // Takes forever...
   }
}
Run Code Online (Sandbox Code Playgroud)

一旦我开始迭代数据,查询就会按预期执行.当单步执行代码时,我立即进入循环,这正是我所希望的 - 这意味着L2S似乎在幕后使用DataReader而不是首先拉取所有数据.但是,一旦我到达break,查询将继续运行并拉出所有其余记录.以下是我对SO社区的问题:

1.)有没有办法阻止Linq-to-SQL在中间执行一个非常大的查询DataReader

2.)如果执行大型Linq-to-SQL查询,是否有办法阻止DataContext填充返回的每个对象的更改跟踪信息.基本上,我可以使用DataReader技术以短的对象生命周期进行大型查询,而不是填满内存吗?

如果这不是内置于DataContext自身的功能并且需要通过一些自定义扩展功能,我没关系.我只是想利用Linq的简单性和强大功能来处理夜间处理任务的大型查询,而不是依赖于T-SQL.

Ahm*_*eed 7

1.)有没有办法阻止Linq-to-SQL在使用DataReader的过程中完成一个非常大的查询的执行?

不完全的.最终执行查询后,基础SQL语句将返回匹配记录的结果集.查询将推迟到该点,但不会在遍历期间延迟.

对于您的示例,您可以简单地使用,records.Take(3)但我理解您停止进程的实际逻辑可能是SQL外部或不易翻译.

您可以通过构建强类型LINQ查询然后使用旧式ADO.NET执行它来使用组合方法.缺点是你失去了到类的映射,并且必须手动处理SqlDataReader结果.这方面的一个例子如下所示:

var query = from c in Customers
            where c.ID < 15
            select c;

using (var command = dc.GetCommand(query))
{
    command.Connection.Open();
    using (var reader = command.ExecuteReader())
    {
        int i = 0;
        while (reader.Read())
        {
            Customer c = new Customer();
            c.ID = reader.GetInt32(reader.GetOrdinal("ID"));
            c.Name = reader.GetString(reader.GetOrdinal("Name"));
            Console.WriteLine("{0}: {1}", c.ID, c.Name);
            i++;
            if (i > 3)
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2.)如果执行大型Linq-to-SQL查询,是否有办法阻止DataContext填充返回的每个对象的更改跟踪信息.

如果您对特定查询的意图是将其用于只读目的,则可以通过将DataContext.ObjectTrackingEnabled属性设置为false 来禁用对象跟踪以提高性能:

using (var dc = new MyDataContext())
{
    dc.ObjectTrackingEnabled = false;
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

您还可以阅读此MSDN主题:如何:以只读方式检索信息(LINQ to SQL).