实体框架-包括从基数据库集派生的集合

本文关键字:派生 集合 数据库 框架 -包 实体 | 更新日期: 2023-09-27 18:22:30

我要问的主要问题是:

是否有一种方法可以保持DbSet基于基类,并且仍然支持在只需要Id的单个检索方法中急切加载派生对象?答案可能是你做不到。我只是希望我忽略了什么

考虑以下情况:

//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足够聪明,可以知道基本对象何时实际上是派生对象,并在保存时填充附加字段,以及将对象检索为派生对象。

但是,如果我将派生类更改为:

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中检索完整的对象,因为我无法将其更改为在Base不知道存在的集合上有一个热切的include。

我可以虚拟化集合,这样当映射发生时它就会延迟加载,但我想知道,这是根本问题:


更新:从本质上讲,我只想知道,如果我只有一个Id可以用于检索,那么下面的方法不会起作用,但有类似的方法吗?

context.Bases.Include(x => ((Derived)x).Lookup).FirstOrDefault(x => x.Id == id)

用例是我有一个列表页面。该页面不需要关心它是什么类型,因为它只有基本属性。如果我进入其中一个编辑页面,服务器只会收到Id。

如果这是我在检索后构建DTO时发生的唯一方法,我会接受惰性加载,但我想知道是否有一些我不知道的modelBuilder EF配置,或者是否有一种我还没有找到的写项目查询的方法,允许对派生查找集合进行Eager load?

更新2:接受的答案是他让我知道我不能做我希望的事情。在EF用户语音上也发现了这一点。

实体框架-包括从基数据库集派生的集合

从本质上讲,我想知道的是,如果我只有一个Id来进行检索,下面的方法不会起作用,但有类似的方法吗?

如果派生对象使用某种类型的实体框架继承;映射每类型表(TPT)继承或映射每层次表(TPH)继承,或映射每具体类表(TPC)继承。

然后

db.Bases
  .OfType<Derived>()
  .Include(d => d.Lookup)
  .Where(d => d.Id = someId)
  .ToList();

否则,则不会。