假设我有以下内容:
private IEnumerable MyFunc(parameter a)
{
using(MyDataContext dc = new MyDataContext)
{
return dc.tablename.Select(row => row.parameter == a);
}
}
private void UsingFunc()
{
var result = MyFunc(new a());
foreach(var row in result)
{
//Do something
}
}
根据文档,linq 执行将推迟到我实际枚举结果时,该结果出现在 foreach 的行中。但是,using 语句应强制在调用 MyFunct() 结束时可靠地收集对象。
实际发生了什么,处理器何时运行和/或结果运行?
我唯一能想到的是延迟执行是在编译时计算的,所以实际调用被编译器移动到 foreach 的第一行,导致 using 正确执行,但直到 foreach 行才运行? 有没有大师可以提供帮助?
编辑:注意:此代码确实有效,我只是不明白如何。
我做了一些阅读,并在我的代码中意识到我调用了 ToList() 扩展方法,该方法当然会枚举结果。勾选答案的行为对于回答的实际问题是完全正确的。
抱歉造成任何混淆。
最佳答案
我希望这根本行不通; Select
被延迟,所以此时没有数据被消耗。但是,由于您已经处理了数据上下文(在离开 MyFunc
之前),它将永远无法获取数据。更好的选择是将数据上下文传递给方法,以便消费者可以选择生命周期。另外,我建议返回 IQueryable<T>
以便消费者可以“组合”结果(即添加 OrderBy
/Skip
/Take
/Where
等,并使其影响最终查询):
// this could also be an instance method on the data-context
internal static IQueryable<SomeType> MyFunc(
this MyDataContext dc, parameter a)
{
return dc.tablename.Where(row => row.parameter == a);
}
private void UsingFunc()
{
using(MyDataContext dc = new MyDataContext()) {
var result = dc.MyFunc(new a());
foreach(var row in result)
{
//Do something
}
}
}
更新:如果您(评论)不想延迟执行(即您不希望调用者处理数据上下文),那么您需要评估结果。您可以通过调用 .ToList()
来完成此操作或 .ToArray()
在结果上缓冲值。
private IEnumerable<SomeType> MyFunc(parameter a)
{
using(MyDataContext dc = new MyDataContext)
{
// or ToList() etc
return dc.tablename.Where(row => row.parameter == a).ToArray();
}
}
如果你想在这种情况下保持延迟,那么你需要使用“迭代器 block ”:
private IEnumerable<SomeType> MyFunc(parameter a)
{
using(MyDataContext dc = new MyDataContext)
{
foreach(SomeType row in dc
.tablename.Where(row => row.parameter == a))
{
yield return row;
}
}
}
这现在在不传递数据上下文的情况下被推迟。
关于c# - LINQ 如何在 using 语句中延迟执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/456691/