Fluent API 和建立 1:* 关系

Posted

技术标签:

【中文标题】Fluent API 和建立 1:* 关系【英文标题】:Fluent API and building a 1:* relationship 【发布时间】:2017-07-22 12:40:21 【问题描述】:

我有两个具有 1 对 1..* 关系的表(这意味着“状态”表中总会有特定 ID 的记录。

|Area|                |      Status     |
------                -------------------
|[Key]  ID |  ---->   |[Key]     ID     |
|      Name|          |[Key] Start Date |
                      |      End Date   |

我的数据层中建立了如下关系。

面积

HasMany(s => s.Statuses)
    .WithRequired()
    .HasForeignKey(s => s.Id);

状态

HasRequired(a => a.Area)
   .WithMany(s => s.Statuses)
   .HasForeignKey(s => s.Id);

我有一个通用的“AllIncluding”方法,用于收集相关数据。在调试器中,我可以查看查询并将其复制/粘贴到我的 Oracle 数据库并执行。它按我的预期工作并返回适当数量的行。 问题是在调试器中执行后,我浏览记录集并找到完全不同的数据集(缩减集)。

我的想法是,这是因为我按照图中的描述定义了键。我可以创建有关... the upper bound of the multiplicity of the Dependent Role must be '1' 的错误,还可以通过简单地修改状态表上的键来修改调试器中返回的记录集。 这似乎表明记录关系正在尝试删除状态表中的重复项以创建联接?我试图通过执行 group by trunc(start_date) 或其他类似查询在 Oracle 中重新创建它,但无法找到返回结果的确切行。 它只是证实了我的怀疑,Fluent API 中定义的映射和关系一定是错误的,但我不确定如何正确表示。

最终我只想在 Fluent API 中创建一个 1 -> 1..* 关系。

谢谢!

【问题讨论】:

查看类定义会有所帮助。似乎Status 实际上是Area 和一些存储“真实”状态的状态表之间的连接类,否则多对多关系似乎更合适。但是从你的描述中很难拼凑出发生了什么。 【参考方案1】:

这只是证实了我的怀疑,Fluent API中定义的映射和关系一定是错误的

    使用 Fluent API 映射关系时要非常小心。具体来说,使用的With 方法重载必须与导航属性的存在/不存在完全匹配。 WithRequired().WithRequired(a => a.Statuses) 完全不同。当您没有导航属性时使用前者,否则使用后者。在您的情况下,您错误地使用了无参数重载。

    始终在一处配置关系。这种关系是涉及两个实体的一件事——不需要在两个地方复制它,更重要的是,它容易出错。目前您有两种定义,一种是正确的(用于Status),一种是不正确的(用于Area)。最终结果是 EF 将它们视为两种不同的关系,进而导致错误的结果。

所以,要么从Area 中删除代码,然后将Status 中的代码原样保留:

HasRequired(s => s.Area)
    .WithMany(a => a.Statuses)
    .HasForeignKey(s => s.Id);

或从Status 中删除代码并在Area 中使用以下代码:

HasMany(a => a.Statuses)
    .WithRequired(s => s.Area)
    .HasForeignKey(s => s.Id);

【讨论】:

我试图从 Area 表中删除关系,但我开始收到一个错误,即找不到 Area_Id 值。我知道这是由于没有定义关系,所以添加了 .HasForeignKey() 子句。 我认为您可能正在做某事,因为我更改了状态表中的键以包含其他人并且看到了新结果 根据您显示的内容,表中必须没有 Area_Id 列,因为根据您的设置,Status.ID 应该是 Area 的 FK。希望您在Status 配置中也使用了HaskKey(s => new s.Id. s.StartDate 之类的东西。无论如何,没有看到确切的实体类和完整的配置,我无话可说。

以上是关于Fluent API 和建立 1:* 关系的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Fluent API 映射这种冗余的父子关系

EF Core中通过Fluent API配置一对一关系

EF Core中通过Fluent API配置一对一关系

Entity Framework Code First Fluent API - 配置关系

EF Core中通过Fluent API配置一对多关系

如何使用 Fluent API 配置从 AspNetUsers 表到...的一对多关系