我有一个带有简单导航属性A
的实体B
。对于A
的任何给定实例,我们期望几个相关的千个B
实例。
我决不会这样说:
foreach(var x in A.B) { ... }
相反,我只对进行聚合操作感兴趣,例如
var statY = A.B.Where(o => o.Property == "Y");
var statZ = A.B.Where(o => o.CreateDate > DateTime.Now.AddDays(-1));
据我所知,EF实例化了数千个对B的引用,并在内存中执行这些操作。这是因为导航属性使用EntityCollection。相反,我希望它尽可能在SQL级别执行这些查询。
我目前的预感是导航属性可能不是正确的方法。我不喜欢EF,所以我对其他方法持开放态度。但是如果可能的话,我很想知道在EF下正确的方法。
(我正在使用EF4。)
答案 0 :(得分:12)
CreateSourceQuery似乎可以解决问题。
所以我的例子现在是:
var statY = A.B.CreateSourceQuery().Where(o => o.Property == "Y");
var statZ = A.B.CreateSourceQuery().Where(o => o.CreateDate > DateTime.Now.AddDays(-1));
答案 1 :(得分:-1)
你应该知道一件事。源自IQueryable<>的成员在服务器上执行,而不是在内存中执行。从IEnumerable<>派生的成员在内存中执行。 例如
var someEntities = db.SomeEntities; <-- returns an IQueryable<> object. no data fetched. SomeEntities table may contain thousands of rows, but we are not fetching it yet, we are just building a query.
someEntities = someEntities.Where(s => s.Id > 100 && s.Id < 200); <-- creates expression tree with where statement. The query is not executed yet and data is not fetched on the client. We just tell EF to perform a where filter when query will execute. This statement too returns an IQueryable<> object.
var entities = someEntities.AsEnumerable(); <-- here we tell EF to execute query. now entities will be fetched and any additional linq query will be performed in memory.
您还可以使用foreach获取数据,调用ToArray()或ToList&lt;&gt;。
希望你明白我的意思,对不起我的英语:)