实体框架 5:代码优先的循环关系问题

2024-02-07

我明白为什么 EF 不允许 PK/FK 关系中的“循环引用”。我正在寻求有关如何更改模型以使以下场景发挥作用的建议。

Scenario

三个实体:Employee, Agency, WorkRecord。他们的目的是记录员工工作所花费的时间。Employee然后包含对Agency他/她受雇于,并且他/她WorkRecord包含对Agency工作已经完成了。

public class Employee
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public int AgencyId { get; set; }
    public virtual Agency Agency { get; set; }

    public virtual IEnumerable<WorkRecord> WorkRecords { get; set; }
}

public class Agency
{
    [Key]
    public int Id { get; set; } 
}

public class WorkRecord
{
    [Key]
    public int Id { get; set; } 

    public int Hours { get; set; } 

    public int AgencyId { get; set; } 
    public virtual Agency Agency { get; set; } 

    public int EmployeeId { get; set; }
    public virtual Employee { get; set; }
}

就像这样,它会发牢骚:FK_dbo.WorkRecords_dbo.Employees_EmployeeId导致循环参考。

实验

我的第一个想法是因为双向虚拟属性,所以我决定将两者中的一个指定为具有单向关系的顶级实体:

首先,我指定了WorkRecord作为顶级实体并删除虚拟WorkRecords参考参考来自Employee实体...产生相同的消息。

其次,我做了Employee顶级实体,留下其虚拟WorkRecords收集,并删除虚拟Employee参考属性来自WorkRecord实体...工作正常,但没有实现我的目标。

经过更多调查,我发现是两个实体上的 Agency 虚拟引用属性导致了循环引用。如果一个实体删除这一点,Employee/WorkRecord实体关系在各个方向上发挥作用。

问题:

所以,我可以清楚地问 - 我如何表达这种商业模式,使用WorkRecord作为我的顶级实体,而不会让 EF5 感到不安?


听起来您只是想摆脱 EF 的困扰,但我认为这实际上表达了数据耦合中的一个有效问题。例如,如果将 AgencyId 同时绑定到 WorkRecord 和 Employee,则更新 WorkRecord 上的 AgencyId 将级联到 Employee。然后将级联到 WorkRecord 等。因此“循环引用”。您确实应该指定哪些数据对象将“拥有”与代理机构的关系。

就我个人而言,我怀疑最自然的绑定是从工作记录中引用代理。我可以看到这样一种情况:员工可能从一个机构转移到另一个机构,但工作记录从一个机构转移到另一个机构会困难得多。事实上,没有 WorkRecord 的 Employee 也不能被称为真正的 Employee。如果您确定是这种情况,那么我会从“员工”中删除“代理机构”引用。如果您需要从员工处前往代理机构,那么您可能should无论如何都要检查一下工作记录。

然而,所有这些都只是概念性的。我怀疑,如果您使 Employee 上的 AgencyId 可以为 null,那么 EF 就不会再抱怨了(而且您might希望两者都是可选的)。这应该使得员工的更新有效,而无需要求使用 WorkRecord 进行循环更新。我必须测试一下才能验证,但我怀疑它是正确的。

public class Employee
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public int? AgencyId { get; set; }
    public virtual Agency Agency { get; set; }

    public virtual IEnumerable<WorkRecord> WorkRecords { get; set; }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架 5:代码优先的循环关系问题 的相关文章

  • 在 C++ 中,当我将值传递给函数时,它是否总是转换为适当的类型?

    如果我有一个像这样的函数void func size t x 我称该函数为func 5 5 立即转换为size t类型 这通常适用于所有类型吗 我问这个问题是因为我发誓我见过人们编写代码 他们做类似的事情func 5 0 将 5 作为双精度
  • 沿着长数据序列在固定大小的移动窗口中查找中值

    给定一个数据序列 可能有重复项 一个固定大小的移动 窗口 从数据开始处每次迭代时移动窗口 序列 使得 1 从窗口中删除最旧的数据元素并添加新数据 元素被推入窗口 2 求每次移动时窗口内数据的中位数 以下帖子没有帮助 有效地找到随机序列的中值
  • 为什么在 OpenCV 中访问该矩阵时出现内存错误?

    我只是想写入给定大小的矩阵 当我在 Valgrind 中运行该程序时 出现内存错误 如下所示 主要 cpp include
  • Windows CE 6.0 和运行时链接到调试 DLL /MDd

    我在 x86 PC 上使用 Windows CE 6 0 R3 我已经为该平台构建了 NK bin 和 SDK 但我有一些问题需要了解如何使用 MTd 调试 DLL 构建控制台应用程序 如果我尝试构建这个 main c with MDd i
  • Visual Studio 2015 C# 找不到参考

    我在使用 Visual Studio 2015 和 C 时遇到了问题 在同一解决方案中添加对其他项目的引用时 Visual Studio 找不到所有类 例如 我创建了一个单元测试项目 我添加了对我创建的通信项目的引用 库中有 10 个类 但
  • 如何(可移植地)在 C 和 C++ 中获取 DBL_EPSILON

    我正在 Linux AS 3 上使用 GCC 3 4 并试图找出DBL EPSILON 或者至少是一个不错的近似值 我怎样才能以编程方式获取它 在 C 中是std numeric limits
  • 使用 Process.Start() 打开文件夹时访问被拒绝异常

    我有一个 C 中的 winforms 应用程序 我必须在其中打开某个文件夹 我用 System Diagnostics Process Start pathToFolder 这会导致以下异常 System ComponentModel Wi
  • 是否可以获取指向装箱非托管值类型的指针?

    是否可以获取指向装箱非托管值类型的指针 而无需编写对每个支持的类型进行强制转换的大型 switch 语句 就像是 object val Contains a boxed unmanaged value such as int long by
  • 如何实现可变虚拟成员函数

    所以我有这个功能 virtual void CallRemoteFunction const char pServerGameObjectId const char pFunctionName OVariant arg1 OVariant
  • 为什么Windsor只能拦截虚方法或接口方法?

    我正在阅读文档 发现如果不使用接口 那么 Windsor 只能拦截虚拟方法 这是 Windsor 的限制还是 C 语言的限制 我正在寻找深入的答案 C 语言在这里完全无关 问题是拦截在运行时级别如何工作 一种技术是从类继承 实现接口并将其用
  • 如何在Phone类库项目中添加ResourceDictionary并访问它

    我正在开发一个项目 其中我有一个引用图书馆项目的子项目 在我的库项目 电话类库 中 如何创建 ResourceDictionary xaml 其中我需要添加一些样式并在 xaml 文件和 cs 文件中使用它 我需要访问 xaml 文件中的
  • 为什么 C++20 范围不只提供管道语法?

    我知道这个问题听起来很奇怪 所以这里有一些背景信息 最近 我很失望地了解到 C 20 范围内的映射缩减并不像人们所期望的那样工作 即 const double val data transform accumulate 不起作用 你必须这样
  • 如何明智地解释这个编译器警告?

    当我执行这段代码时question https stackoverflow com a 51056490 2411320 我收到这个警告 warning format d expects argument of type int but a
  • EF 5.0 枚举未生成

    背景我在安装了 Net 4 5 的机器上使用 VS 2010 我读到这是就地安装 覆盖了 net 4 0 版本 我的项目仍然针对 4 0 而 4 5 选项不可用 但被告知没关系 因为 4 5 是就地安装 然后 我通过 nuget 安装了 E
  • 更改成员资格、角色等的默认连接字符串

    默认情况下 我的网络应用程序似乎正在使用LocalSqlServer作为用于任何应用程序服务 例如成员资格 角色 身份验证 等 的连接字符串 有什么方法可以更改默认连接字符串应该是什么 默认值是 LocalSqlServer 似乎很随意 我
  • 使用 Node.js 访问用 C++ 编写的 SDK

    我有一个用 C 语言编写的 SDK 可以与我的扫描仪设备进行通信 我需要开发一个可以访问扫描仪设备的电子应用程序 我知道有很多库可用于扫描仪 但我想使用这个 SDK 因为它允许我访问设备的完整功能 而且它是由设备制造商提供的 那么 有没有什
  • C 中函数“fgets”的参数太少

    每当我编译这个错误时 我都会收到该错误 但我不知道为什么 我直接从书上抄袭这个 有人可以帮忙吗 include
  • 使用 QTestLib 时抑制 qDebug

    我正在向 Qt 中的项目添加单元测试 并希望使用 QTestLib 我已经设置了测试并且它们运行良好 问题是在项目中我们重写了 qDebug 以输出到我们自己的日志文件 这在运行应用程序时效果很好 问题是当我测试类时 它有时会开始记录 然后
  • 为什么 sql 字段名称中不应该包含逗号?

    人们一直告诉我列名中不应包含空格 我只是想知道 这是为什么 这是我为学校创建的一些数据库表遇到的问题 字段名称包括 Preble 和 Darke 相反 它们需要是 普雷布尔县 俄亥俄州 和 达克县 俄亥俄州 如果它们是行名称 我只需创建一个
  • File.Move 的原子性

    我想将目录中的文件重命名为原子事务 该文件不会更改目录 该路径作为 NTFS 文件系统的 UNC 路径提供 可能位于服务器 03 或 08 上 File Move 对于这些目的来说是原子的吗 例如 它要么成功完成 要么失败 以使原始文件仍然

随机推荐