【发布时间】:2015-11-18 03:08:58
【问题描述】:
我要问的主要问题是:
有没有办法保持基于基类的 DbSet 并且仍然支持在仅需要 Id 的单个检索方法中对 Derived 对象进行预加载?答案可能是你不能。我只是希望我忽略了一些东西。
考虑以下情况:
//Models
public class Base {
public int Id {get;set;}
public string BaseProp {get;set;}
}
public class Derived : Base {
public string DerivedProp {get;set;}
}
//Context
DbSet<Base> Bases {get;set;}
//Saving
public void Save(Base obj){
// Adding only for brevity
context.Bases.Add(obj)
context.SaveChanges();
}
//Retrieval
public Base Retrieve(int id){
return context.Bases.FirstOrDefault(x => x.Id == id);
}
EF6 足够聪明,可以知道 Base 对象何时实际上是 Derived 对象,并在保存时填充其他字段并将对象检索为 Derived 对象。
但是,如果我将派生类更改为:
public class Derived : Base {
public string DerivedProp {get;set;}
public ICollection<SomeLookup> Lookup {get; set;} // Creates junction table with Id/LookupId as columns
}
我仍然可以保存(并且它使用选定的查找很好地填充了联结表),但我不再可以检索我的 Base DbSet 中的完整对象,因为我无法将它更改为在一个集合中包含一个热切的包含基地不知道存在。
我可以虚拟化集合,以便在映射发生时延迟加载,但我想知道,这是根本问题:
更新:基本上我想知道的是,如果我只有一个 Id 可用于我的检索,那么以下内容将不起作用,但有类似的东西吗?
context.Bases.Include(x => ((Derived)x).Lookup).FirstOrDefault(x => x.Id == id)
用例是我有一个列表页面。该页面不需要关心它是什么类型,因为它只有基本属性。如果我进入其中一个编辑页面,服务器只会传递 ID。
如果这是我在检索后构建 DTO 时会发生的唯一方法,我会接受延迟加载,但我想知道是否有一些我不知道的 EF 配置用于 modelBuilder 或如何编写一个我尚未找到的项目查询,该查询允许对该派生查找集合进行急切加载?
更新 2: 基于他让我知道我不能做我希望的事情而接受的答案。还发现了this on the EF uservoice。
【问题讨论】:
-
你能展示从数据库获取数据的代码吗?当您获得基本 dbset 并需要包含派生导航属性时,用例是什么?
-
@KirillBestemyanov 我更新了这个问题。很可能允许延迟加载很好,我只是无缘无故地过早优化(谁知道,结果 SQL 可能更糟)。我只是好奇这样的东西是否真的可以工作,因为我什至惊讶于 Base & Derived 的东西和开箱即用的效果一样好。
-
你知道当前 id 的派生类型是什么吗?如果是,您可以使用泛型 Set
标签: c# entity-framework ef-code-first