【问题标题】:Can you get DataReader-like streaming using Linq-to-SQL?您可以使用 Linq-to-SQL 获得类似 DataReader 的流式传输吗?
【发布时间】:2010-10-21 18:51:30
【问题描述】:

我使用 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...
   }
}

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

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

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

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

【问题讨论】:

    标签: c# linq-to-sql


    【解决方案1】:

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

    2.) 如果您执行大型 Linq-to-SQL 查询,有没有办法防止 DataContext 从填满 更改每个人的跟踪信息 对象返回。

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

    using (var dc = new MyDataContext())
    {
        dc.ObjectTrackingEnabled = false;
        // do stuff
    }
    

    您还可以阅读此 MSDN 主题:How to: Retrieve Information As Read-Only (LINQ to SQL)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多