自引用实体和插入顺序 - 使用 Entity Framework Code First

2024-01-12

我有两个如下所示的实体:

public class AssetSession
{
   [Key]
   public Guid Id { get; set; }
   public string RoomNumber { get; set; }
   public Contact Contact { get; set; }
   public virtual List<Asset> Assets { get; set; }
}

public class Asset
{
   [Key]
   public Guid Id { get; set; }
   public Guid? ParentId { get; set; }
   [ForeignKey("ParentId")]
   public Asset Parent { get; set; }
   public string Barcode { get; set; }
   public string SerialNumber { get; set; }
   public Guid AssetSessionId { get; set; }
   [ForeignKey("AssetSessionId")]
   public AssetSession AssetSession { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Entity<Asset>()
      .HasOptional(t => t.Parent)
      .WithMany()
      .HasForeignKey(t => t.ParentId);
}

AssetSession 与 Asset 具有一对多关系。一切都运行良好,直到最近我在 Asset 上引入了自引用实体(称为 Parent)。

我的问题是,在插入新的 AssetSession 记录时进行一些 SQL 分析后,EF 现在似乎尝试首先插入引用 AssetSession 上不存在的 FK 的资产,因此我收到以下错误:

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Assets_dbo.AssetSessions_AssetSessionId"

该错误是不言自明的,但我不明白的是为什么 INSERT 语句的顺序不是首先创建 AssetSession 以便 Assets 引用正确的 AssetSession。

我的插入代码如下所示:

using (var context = new AssetContext())
{
   var assetSession = jsonObject; // jsonObject being passed into the method

   var existingSession = context.AssetSessions.FirstOrDefault(c => c.Id == assetSession.Id);

   if (existingSession == null)
   {
      var existingContact = context.Contacts.FirstOrDefault(c => c.Id == assetSession.Contact.Id);

      if (existingContact != null)
      {
         context.Contacts.Attach(existingContact);
         assetSession.Contact = existingContact;
      }

      context.Entry(assetSession).State = EntityState.Added;
      context.SaveChanges();    
   }
}

我在使用 EF 的外键时遇到了同样的错误。它可能不相关,但是提供的答案帮助我理解了为什么我收到错误。

EF 和外键问题 https://stackoverflow.com/questions/21869330/entity-framework-inserting-child-objects-in-the-wrong-order/21894251?noredirect=1#21894251

总结 Slauma 的回答,我在 EF 插入之前清除了垂直导航值。这引起了一个问题,尽管这是一个不同的问题,但它可能会有所帮助。

潜在的解决方案

如果您将所有 AssetSession 对象添加到 Asset 对象中,然后执行一个根添加,这应该允许 EF 正确插入两者。

注意:为此,您可能需要在插入对象之前生成 GUID。

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

自引用实体和插入顺序 - 使用 Entity Framework Code First 的相关文章

  • 如何在 Visual Studio 2010 中增强 XAML 设计器?

    当我使用 XAML 设计器时 进入设计器和退出设计器是如此困难和缓慢 当我这样做时 Visual Studio 卡了一段时间 有什么方法可以增强 XAML 设计器和编辑器吗 Ant 保存 XAML 文件时非常慢 这通常意味着您可能有复杂的
  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 如何读取扩展文件属性/文件元数据

    因此 我按照教程使用 ASP net core 将文件 上传 到本地路径 这是代码 public IActionResult About IList
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 如何将自定义 JSON 文件添加到 IConfiguration 中?

    我正在使用 asp net Autofac 我正在尝试加载自定义 JSON 配置文件 并基于该文件创建 实例化 IConfiguration 实例 或者至少将我的文件包含到默认情况下构建的 IConfiguration asp net 中
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 如何正确使用 std::condition_variable?

    我很困惑conditions variables以及如何 安全 使用它们 在我的应用程序中 我有一个创建 gui 线程的类 但是当 gui 是由 gui 线程构造时 主线程需要等待 情况与下面的函数相同 主线程创建互斥体 锁和conditi

随机推荐