我有一个用抽象实体/类构建的 EF4 模型:
请注意State实体如何具有名为Country的导航属性。
注意:我禁用了延迟加载,所以我必须按需加载。
现在,如果我有以下方法:
public Location FindSingle(int id)
{
return _repository.Find().WithId(id).SingleOrDefault();
}
默认情况下,这不会返回任何关联。但是,当我明确想要时,如何动态地预先加载关联?
我不能做到这一点:
return _repository.Find().WithId(id).Include("Country").SingleOrDefault();
因为我正在使用一个名为Location的抽象类,它没有名为“Country”的导航属性。在我实际执行查询之前,我不知道.SingleOrDefault
派生类型是什么。
所以,这就是我必须做的:
public Location FindSingle(int id, bool includeAssociations = false)
{
var location = _repository.Find().WithId(id).SingleOrDefault();
return includeAssociations
? LoadAssociation(location)
: location;
}
private Location LoadAssociation(Location location)
{
// test derived-type, e.g:
var state = location as State;
if (state != null)
return _repository.Find().OfType<State>().Include("Country").WithId(id).SingleOrDefault();
}
本质上,我正在做 2 个相同的电话。它有效吗?是的。漂亮吗?不,这并不是真正的“急切加载”。
我知道这不是正确的解决方案,你们能想到正确的解决方案吗?(是的,我知道我可以使用存储过程,但我真的很想在这里查看我的存储库/模型,以便实体正确地附加到图表上,准备好进行编辑)。
即使.Include
导致左外连接,问题是我正在处理“位置”实体集。我需要.Include
在“状态”上,但“状态”属于“位置”实体集(派生类属于其父实体集)。
所以我想我的问题实际上很笼统——当我们事先不知道孩子是什么时,我们如何在抽象实体的孩子上做一个 .Include ?
请记住,我不能.OfType<T>()
先使用(然后是派生类型上的 .Include),因为我不知道 T 是什么(调用代码也不知道),因此这里不能使用泛型。