EF 构建 EntityCollection,但我(认为我)想要 IQueryable

发布于 2024-10-05 19:42:12 字数 575 浏览 1 评论 0原文

我有一个带有简单导航属性 B 的实体 A。对于任何给定的 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。)

I have an entity A with a simple navigation property B. For any given instance of A, we expect several related thousand instances of B.

There is no case where I call something like:

foreach(var x in A.B) { ... }

Instead, I'm only interested in doing aggregate operations such as

var statY = A.B.Where(o => o.Property == "Y");
var statZ = A.B.Where(o => o.CreateDate > DateTime.Now.AddDays(-1));

As far as I can tell, EF instantiates thousands of references to B and does these operations in memory. This is because navigation properties use EntityCollection. Instead, I'd like it to perform these queries at the SQL level if possible.

My current hunch is that Navigation Properties may not be the right way to go. I'm not attached to EF, so I am open to other approaches. But I'd be very interested to know the right way to do this under EF if possible.

(I'm using EF4.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟柳画桥 2024-10-12 19:42: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));

CreateSourceQuery seems to do the trick.

So my examples would now be:

var statY = A.B.CreateSourceQuery().Where(o => o.Property == "Y");
var statZ = A.B.CreateSourceQuery().Where(o => o.CreateDate > DateTime.Now.AddDays(-1));
一片旧的回忆 2024-10-12 19:42:12

有件事你应该知道。从 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<> 来获取数据。

希望你明白我的意思,并对我的英语感到抱歉:)

There's one thing you should know. Members that derives from IQueryable<> are executed on the server, not in memory. Members which are derived from IEnumerable<> is executed in memory.
for example

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.

you can also fetch the data using foreach, calling ToArray() or ToList<>.

Hope you understand what I mean, and sorry for my english :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文