总结:我有哪些选项可以让实体的子集合的 LINQ 查询使用“LINQ-to-Entities”而不是“LINQ-to-Objects”,换句话说,导致使用生成的查询提供程序SQL而不是执行正常的枚举?这是使用 EF5、DbContext 和 POCO 实体。
另一种看待它的方式是:如何在不更改所有 LINQ 查询的情况下让实体的子集合(ICollection<> 类型)像旧式 EF1 实体的 EntityCollection<> 属性一样工作?
这是我的情况:
我有一个 Entity Framework 5 项目,我正在切换到使用 DbContext 和 POCO 实体而不是 ObjectContext 和默认生成的实体。
在我的代码中,我的查询看起来像这样:
var thirdEntities = from secondEntity in firstEntity.SecondEntities
select secondEntity.ThirdEntity;
这过去只导致单个数据库命中,因为 firstEntity.SecondEntities 是 EntityCollection 类型。这导致使用 LINQ to Entities,它将整个 LINQ 语句转换为 SQL。
但是,当我切换到使用 DbContext 和 POCO 时,上面的语句现在会导致大量数据库命中。这是导致问题的 POCO 类属性:
public class FirstEntity {
public FirstEntity() {
this.SecondEntities = new HashSet<SecondEntity>();
}
public virtual ICollection<SecondEntity> SecondEntities {get; set;}
}
这是因为 firstEntity.SecondEntities 现在是 ICollection 类型(HashSet 的实际类型)。由于延迟加载已打开,因此会命中数据库以填充 firstEntity.SecondEntity,然后将该结果枚举 X 次以填充 secondEntity.ThirdEntity 的每个实例。
我找到的一个解决方案是将第一个查询更改为:
var thirdEntities = from secondEntity in dbContext
.Entry(firstEntity)
.Collection(e => e.SecondEntities)
.Query()
select secondEntity.ThirdEntity;
但是,我不想这样做。我宁愿以某种方式更改 POCO,这样我就不必更改所有 LINQ 查询。