我已经使用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.
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).
归档时间: |
|
查看次数: |
6318 次 |
最近记录: |