【发布时间】:2019-05-10 15:19:57
【问题描述】:
我必须通过 FluentAPI 定义具有多对多关系的 2 个实体类。 Entity1 具有带有相关 Entity2 对象的虚拟集合。 Entity2 没有这个集合,因为我不需要它。 我的课程如下所示:
internal class Franchisee : UserAccount //abstract base class with more properties
{
public virtual ICollection<FranchiseOffice> FranchiseOffices { get; set; }
}
internal class FranchiseOffice: Office //abstract base class
{
<many properties, but no collection for Franchisee-objects>
}
多对多关系的配置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<CoreModel, Migrations.Configuration>());
//many-to-many relationship with only one navigation property
modelBuilder.Entity<Franchisee>().HasMany(u => u.FranchiseOffices).WithMany().Map(m =>
{
m.MapLeftKey("FranchiseeId");
m.MapRightKey("FranchiseOfficeId");
m.ToTable("FranchiseOffices");
});
}
工作原理:保存实体并通过导航属性将它们链接在一起。数据库中的数据看起来不错;映射表 'FranchiseOffices' 在那里并填充了数据。
什么不起作用:当我加载加盟商时,集合 'FranchiseOffices' 为 NULL,尽管数据库中存在它的数据。
我可以看到与在线示例的唯一区别是我在两边都使用了继承的类。我尝试明确查询子类,但结果是一样的。有什么想法吗?
【问题讨论】:
-
这里的“加载”是什么意思“当我加载加盟商时” - 您是否要求 EF 急切加载相关集合,例如
Include(f => f.FranchiseOffices)?如果没有,并且您依赖延迟加载,是否为用于加载实体的上下文启用了延迟加载和代理创建? -
好吧,这确实起到了作用。延迟加载和代理创建默认打开,似乎不会影响结果。但是,手动使用 Include("FranchiseOffices") 有效。可悲的是,这对我来说不是解决方案,原因如下: 1. 在查询时,我不知道查询的实体是否属于“特许经营者”类型,因此不能使用 Include()(请记住:特许经营者是一个孩子-班级)。 2. 必须在多对多关系中手动包含所有相关实体是不好的设计;我想找到 EF 不自动加载它们的根本原因。感谢您的帮助!
-
我也试过在另一端添加第二个导航属性;使其成为“正常”的多对多关系。但相关实体仍未自动加载。
-
如果我理解正确,那是 延迟加载 不起作用。如果您在问题中提供该信息以及可重复的示例,那就太好了 - 例如,
UserAccount和Office只是基本 类 或者它们是基本 实体(即,EF 支持的数据库继承策略之一的一部分)。示例模型、配置和无效查询将有助于识别问题并寻求解决方案。 -
谢谢伊万,我找到了根本原因:)
标签: entity-framework many-to-many ef-fluent-api