假设你需要书写如下的查询脚本代码:
var possibleBuyers=
from p in ctx.People
where p.Address.City == “Sammamish” && InMarketForAHouse(p)
select p;
理论上,上面的代码需要有一个SQL翻译方法来解析InMarketForAHouse方法。
Now theoretically this is possible so long as there is a SQL translation for InMarketForAHouse.
在EF4.0中,你素要为需要的模型或者数据库编写CLR存储器。
In EF 4.0 you do this by creating a CLR stub for the required Model or Database function.
假设没有SQL翻译,或许函数需要使用一些数据库中没有的对象,所以你现在需要把LINQ语句拆分成两个部分,一部分是用于Entity查询的基础语句部分,另一部分是依赖于对象查询的依赖语句部分。
你可以尝试着如下的写法:
You might try something like this:
var partialFilter = from p in ctx.People
where p.Address.City == “Sammamish”
select p;
var possibleBuyers = from p in partiallyFilter
where InMarketForAHouse(p);
select p;
但是上面的写法并没有实质性的变化,IQueryable (ctx.People)将依然需要一个翻译机制来翻译InMarketForAHouse(..)方法。
你需要调用AsEnumerable()方法,来隔离上面的两部分语句:
var possibleBuyers = from p in partiallyFilter.AsEnumerable()
where InMarketForAHouse(p);
select p;
AsEnumerable() 方法用LINQ to Objects的语法接管了所有的子查询请求,因此LINQ to Entities将不会再要求翻译InMarketForAHouse(..).方法。
下面还有需要注意的地方:
你可能为了或其少量的数据结果要从数据库中先检索出大量的数据,这将会对性能有所影响,所以在进行查询的时候,要让你自己知道你需要取多少数据出来enumerating。问题是ObjectContext不仅仅默认执行了当前对象的enumerating,它还会自动加载相关的其他对象,当然这个特殊的问题可以通过使用NoTracking查询加以克服,但你会遇到其他的问题,你将在加载这些其他对象以后才可以执行更新操作。所以这里需要一下权衡。