正如标题所示,我正在寻找一种与包含(include)结合使用where子句的方法。
这是我的情况:
我负责维护一个代码问题严重的大型应用程序。 改变太多的代码会导致到处都是错误,因此我正在寻找最安全的解决方案。
假设我有一个Bus对象和一个People对象(Bus有一个指向People集合的导航属性)。 在我的查询中,我需要选择所有只有醒着的乘客的巴士。这只是一个简单的虚拟例子。
在当前的代码中:
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);
}
}
在这段代码之后,上下文被释放,在调用方法中,生成的Bus实体会映射到DTO类(与实体完全一样)。
这段代码导致多次调用数据库,这是不可行的,因此我在MSDN博客上找到了解决方案。
当调试结果时,这个方法效果很好,但当实体映射到DTO(使用AutoMapper)时,我得到一个异常,提示上下文/连接已关闭,对象无法加载。(上下文始终关闭,无法更改这一点:( )
所以,我需要确保所选的乘客已经加载(IsLoaded导航属性也为False)。如果我检查乘客集合,计数也会抛出异常,但乘客集合的“包装相关实体”中还有一个包含我的过滤对象。
是否有办法将这些包装的相关实体加载到整个集合中?(我无法更改automapper映射配置,因为它在整个应用程序中使用)。
还有其他获取活动乘客的方法吗?
任何提示都欢迎...
编辑
Gert Arnold的答案无效,因为数据没有被急切地加载。但是,当我简化代码并删除where时,它被加载了。这真的很奇怪,因为执行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
经过艰苦的努力,Gert Arnold的答案起作用了!正如Gert Arnold所建议的那样,您需要禁用惰性加载并将其保持关闭状态。这将要求对应用程序进行一些额外的更改,因为之前的开发人员喜欢惰性加载 -_-。