EF:包括WHERE子句
正如标题所暗示的那样,我正在寻找一种方法,将WHERE子句与包含结合在一起。
下面是我的情况:我负责支持一个充满代码气味的大型应用程序。更改太多的代码会在任何地方导致错误,所以我正在寻找最安全的解决方案。
假设我有一个对象总线和一个对象人员(总线有一个导航支柱集合人员)。在我的查询中,我需要选择所有的巴斯,只有乘客是清醒的。这是一个简单的虚拟示例。
在现行守则中:
var busses = Context.Busses.Where(b=>b.IsDriving == true);foreach(var bus in busses){
var passengers = Context.People.Where(p=>p.BusId == bus.Id && p.Awake == true);
foreach(var person in passengers)
{
bus.Passengers.Add(person);
}}
在此代码之后,上下文被释放,在调用方法中,生成的总线实体被映射到DTO类(实体的100%副本)。
这段代码会导致对DB的多次调用,这是一个No-go,所以我找到了这个解决方案MSDN博客
这在调试结果时非常有效,但是当实体映射到DTO(使用AutoMapper)时,我得到一个异常,即上下文/连接已经关闭,对象无法加载。(上下文总是关闭的,不能更改以下内容:()
因此,我需要确保选定的乘客已经加载(IsLoedonNavigationProperty也是假的)。如果我检查乘客集合,计数也会抛出异常,但是在PASSECKER集合上也有一个称为“包装相关实体”的集合,其中包含我过滤过的对象。
是否有方法将这些包装好的相关实体加载到整个集合中?(我不能更改Automapper映射配置,因为这在整个应用程序中使用)。
还有别的方法可以让那些活跃的乘客吗?
任何暗示都是欢迎的.。
编辑
格特·阿诺德(GertArnold)的回答不起作用,因为数据没有急切地加载。但是当我简化它并删除加载它的位置时。这确实很奇怪,因为执行SQL在这两种情况下都返回所有乘客。因此,当将结果返回到实体中时,一定会出现问题。
Context.Configuration.LazyLoadingEnabled = false;var buses = Context.Busses.Where(b => b.IsDriving)
.Select(b => new
{
b,
Passengers = b.Passengers
})
.ToList()
.Select(x => x.b)
.ToList();
编辑2
经过很大的努力,格特·阿诺德的作品得到了答案!正如格特·阿诺德(GertArnold)建议的那样,你需要禁用延迟加载,并将其关闭这将要求对appliaction进行一些额外的更改,因为prev开发人员喜欢Lazy加载-_-