【发布时间】:2013-08-16 15:39:45
【问题描述】:
我正在使用 ASP.NET MVC 4 和 Entity Framework 6(代码优先)并且有一些我不想要/不喜欢的奇怪行为:
我有一个实体类Images,它有一个布尔属性IsDeleted,现在我想获取前25张没有被删除的图像,所以我使用了以下代码:
IEnumerable<Image> items = db.Images.Where(i => !i.IsDeleted).Take(25);
由于这非常慢,我进行了更深入的调查并发现,Where(i => !i.IsDeleted) 已经触发了数据库查询,并且所有图像都已加载(并且解析 => 慢),然后检查发生在“代码中”。然后我尝试了Where(i => i.IsDeleted.Equals(false)),它运行良好,并且通过 SQL 进行了检查。
为什么会这样,或者我怎样才能避免这个问题,因为我更喜欢第一种语法?
这可能是 EF 6 测试版的错误还是在所有 EF 版本中都会发生?
更新:
问题是转换为IEnumerable<Image>(我在我的代码中没有在同一行中使用Where,但为了简单起见在这里更改了它),但我也使用它来使用.OrderBy(...).ThenBy(...) 使用Func<T, TKey>-键,并且确实返回 IOrderedEnumerable 而不是 IOrderedQueryable...
更新 2:
使用Expression<Func<T, TKey>>键解决...
【问题讨论】:
-
人力资源部。这很好奇。 Where(i => i.IsDeleted == false) 呢?
-
@Tim: 与
!i.IsDeleted相同,但我认为这可能是我对IEnumerable<Image>的隐式转换,而不是Where(我做了Equals“内联”,但@ 987654337@“在下一行”)-我正在调查... -
@chrfin 好的,这就是原因。当您执行
IEnumerable<Image> items = db.Images;时,您会将数据库中的所有项目都放入内存中,而是使用IQueryable,在几行中创建查询,并且在您真正想要它之前不让它执行。 -
@chrfin 你可以尝试添加
.AsEnumerable(),而不是投射。 -
@KingKing:我错了,因为我在
IEnumerable演员和!演员之前做了Equals测试......
标签: c# sql linq entity-framework entity-framework-6