正如标题所暗示的那样,我正在寻找一种将 where 子句与 include 结合起来的方法。
我的情况是这样的: 我负责支持一个充满代码味道的大型应用程序。 更改太多的代码会导致到处都是 bug,所以我正在寻找最安全的解决方案。
假设我有一个对象 Bus 和一个对象 People (Bus 有一个导航道具 Collection of 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);
}
}
在这段代码之后,上下文被释放,并且在调用方法中,生成的总线实体映射到一个 DTO 类(100% 的实体副本)。
这段代码会导致对 DB 的多次调用,这是一个 No-Go,所以我找到了这个解决方案 在 MSDN 博客上
这在调试结果时非常有效,但是当实体映射到 DTO (使用自动映射器)时,我得到一个异常,上下文/连接已经关闭,对象无法加载。(语境总是封闭的,不能改变这一点: ()
因此,我需要确保选定的乘客已经加载(导航属性上的 IsLoadedonisFalse 也是 False)。如果我检查乘客集合 The Count 也会抛出 Exception,但是在乘客集合中还有一个名为“被包装的相关实体”的集合,它包含我过滤的对象。
是否有方法将这些经过包装的相关实体加载到整个集合中? (我不能更改自动映射器映射配置,因为这在整个应用程序中都使用)。
还有别的方法可以获得活跃的乘客吗?
欢迎任何提示。
Gert Arnold 的回答不起作用,因为数据没有被急切地加载。 但是当我简化它并删除它加载的地方。这非常奇怪,因为在这两种情况下执行 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();
经过许多斗争的答案格特阿诺德工作! 正如 Gert Arnold 建议的那样,您需要禁用惰性加载并保持其关闭。 这将要求对应用程序进行一些额外的更改,因为前面的开发人员喜欢 Lazy Loading-_-