如何在LINQ using语句时推迟执行
-
19-08-2019 - |
题
想象我有以下:
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的第一行中,用正确执行造成的,但不运行,直到在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();
}
}
如果你想保持它在这种情况下延期,那么你需要使用“迭代器块”:
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;
}
}
}
此现延迟而不围绕传递数据上下文。
其他提示
我刚刚发布了另一个暂缓执行解决这一问题这里,包括本示例代码:
IQueryable<MyType> MyFunc(string myValue)
{
return from dc in new MyDataContext().Use()
from row in dc.MyTable
where row.MyField == myValue
select row;
}
void UsingFunc()
{
var result = MyFunc("MyValue").OrderBy(row => row.SortOrder);
foreach(var row in result)
{
//Do something
}
}
在Use()
扩展方法本质上的作用就像一个延迟using
块。
不隶属于 StackOverflow