由于一个或多个外键属性不可为空,因此无法更改该关系

2024-02-09

使用 EF 更新期间出现以下错误:

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当关系发生更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

有没有general如何找到哪些外键属性导致上述错误?

[Update]

对于以下代码导致上述错误的一种情况(我在断开连接的环境中工作,所以我使用graphdiff更新我的对象图),当它想要运行时_uow.Commit();:

public void CopyTechnicalInfos(int sourceOrderItemId, List<int> targetOrderItemIds)
{
  _uow = new MyDbContext();
   var sourceOrderItem = _uow.OrderItems
          .Include(x => x.NominalBoms)
          .Include("NominalRoutings.NominalSizeTests")
          .AsNoTracking()
          .FirstOrDefault(x => x.Id == sourceOrderItemId);


   var criteria = PredicateBuilder.False<OrderItem>();
   foreach (var targetOrderItemId in orderItemIds)
   {
      int id = targetOrderItemId;
      criteria = criteria.OR(x => x.Id == id);
   }
   var targetOrderItems = _uow.OrderItems
                              .AsNoTracking()
                              .AsExpandable()   
                              .Where(criteria)
                              .ToList();

  foreach (var targetOrderItem in targetOrderItems)
  {
        //delete old datas and insert new datas 
        targetOrderItem.NominalBoms = sourceOrderItem.NominalBoms;
        targetOrderItem.NominalBoms.ForEach(x => x.Id = 0);

        targetOrderItem.NominalRoutings = sourceOrderItem.NominalRoutings;
        targetOrderItem.NominalRoutings.ForEach(x => x.Id = 0);
        targetOrderItem.NominalRoutings
                       .ForEach(x => x.NominalTests.ForEach(y => y.Id = 0));
        targetOrderItem.NominalRoutings
                       .ForEach(x => x.NominalSizeTests.ForEach(y => y.Id = 0));
       _uow.OrderItems.UpdateGraph(targetOrderItem, 
                                   x => x.OwnedCollection(y => y.NominalBoms)
                                         .OwnedCollection(y => y.NominalRoutings, 
                                          with => with
                                         .OwnedCollection(t => t.NominalTests)));
   }
   _uow.Commit();
}

在实体框架中,您可以使用外键关联。也就是说,另一个对象的外键表示为两个属性对:原始外键属性(例如NominalRouting.OrderItemId)和对象引用(NominalRouting.OrderItem).

这意味着您可以设置原始值或对象引用来建立外键关联。如果您设置其中一项,EF 会在可能的情况下尝试使另一项保持同步。不幸的是,这也可能会引起原始外键值与其随附引用之间的冲突。

很难说清楚你的情况到底发生了什么。但是,我do知道您将对象从一个父级“复制”到另一个父级的方法......并不理想。首先,更改主键值从来都不是一个好主意。通过将它们设置为0你让物体看起来像新的一样,但它们却不是。其次,您多次将相同的子对象分配给其他父对象。我think结果,您最终会得到大量具有外键的对象value但不是参考.

我说“复制”,因为这就是你似乎想要实现的目标。如果是这样,您应该正确克隆对象并Add他们对每个targetOrderItem。同时,我想知道为什么你(显然)克隆所有这些对象。看起来多对多关联在这里更合适。但那是另一个话题了。

现在你的实际问题是:如何找到冲突的关联?

这非常非常困难。它将需要代码来搜索概念模型并查找外键关联中涉及的属性。然后你必须找到他们的价值观并找到不匹配的地方。足够困难,但与确定何时possible冲突是一个actual冲突。让我通过两个例子来澄清这一点。这里,一堂课OrderItem具有由属性组成的所需外键关联Order and OrderId.

var item = new OrderItem { OrderId = 1, ... };
db.OrderItems.Add(item);
db.SaveChanges();

所以有一个项目OrderId分配和Order= null,EF 很高兴。

var item = db.OrderItems.Include(x => x.Order).Find(10);
// returns an OrderItem with OrderId = 1
item.Order = null;
db.SaveChanges();

再次,一个项目OrderId分配和Order= null,但 EF 抛出异常“关系无法更改...”。

(而且可能发生冲突的情况也比较多)

所以仅仅寻找不匹配的值是不够的OrderId/Order对,您还必须检查实体状态并确切地知道哪些状态组合不允许不匹配。我的建议:忘记它,修复你的代码。

不过,还有一个肮脏的伎俩。当 EF 尝试匹配外键值和引用时,在嵌套树深处的某个位置if它将我们正在讨论的冲突收集到一个成员变量中ObjectStateManager, named _entriesWithConceptualNulls。可以通过一些反射来获得它的值:

#if DEBUG

db.ChangeTracker.DetectChanges(); // Force EF to match associations.
var objectContext = ((IObjectContextAdapter)db).ObjectContext;
var objectStateManager = objectContext.ObjectStateManager;
var fieldInfo = objectStateManager.GetType().GetField("_entriesWithConceptualNulls", BindingFlags.Instance | BindingFlags.NonPublic);
var conceptualNulls = fieldInfo.GetValue(objectStateManager);

#endif

conceptualNulls is a HashSet<EntityEntry>, EntityEntry是一个内部类,因此您只能检查调试器中的集合以了解冲突的实体。仅用于诊断目的!

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

由于一个或多个外键属性不可为空,因此无法更改该关系 的相关文章

  • DispatcherTimer 未按时执行

    我正在使用 c 中的 DispatchTimer 编写一个时钟应用程序 但由于某些原因 我的时钟似乎时不时地跳过 1 秒 例如 52 秒 gt 54 秒 跳过 53 秒 在我看来 计时器并不是每秒都执行一次 DispatcherTimer
  • 更快的算法来计算有多少数字可以被范围内的特定整数整除

    int a b c d 0 cin gt gt a gt gt b gt gt c for int i a i lt b i if i c 0 d cout lt
  • SetWindowsHookEx 函数返回 NULL

    我正在研究 DLL 注入 但收到错误如下 挂接进程失败 87 参数不正确 目标进程和dll都是64位的 注入代码为 BOOL HookInjection TCHAR target TCHAR dll name https msdn micr
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • Android NDK C++“wstring”支持

    我有用 C 编写的源代码 lib 现在我想在 Android NDK 项目 NDK 6 中编译并使用相同的源代码 lib 我能够编译大多数 C 文件 除了基于 std wstring 的功能 在 Application mk 中 当我指定时
  • 如何将pdf页面设置设置为打印属性对话框?

    大家好 我想知道如何设置 pdf 页面设置到打印属性对话框 例如 如果我的 PDF 页面设置为横向 则布局会自动显示横向而不是纵向 如果我的 PDF 页面设置为纵向 则布局会自动显示纵向 我在这个主题上做了很多研发 但没有找到任何满意的链接
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • 特定设备的不同字体大小

    我目前正在开发通用应用程序 我需要分别处理移动设备和桌面的文本框字体大小 我找到了一些方法 但都不能解决问题 使用 VisualStateManager 和 StateTrigger 为例
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • 如何使用泛型类型的 DataContractSerializer 编写自定义序列化器?

    我想编写一个自定义序列化器 用于将会话状态存储到Azure 缓存 预览版 这意味着这个自定义序列化器必须实现IDataCacheObjectSerializer 如果我错了 请告诉我 我需要编写这个自定义序列化程序的原因是我需要序列化一些包
  • 指示泛型返回动态类型的对象

    这个问题是我原来问题的后续问题here https stackoverflow com questions 2541184 using a type object to create a generic 假设我有以下泛型类 简化 class
  • Microsoft.Graph - 如何从具有不同用户名的共享邮箱发送?

    我目前正在将使用 SMTP 的服务代码移植到 Office 365 通过 SMTP 我可以使用 发件人 字段在来自共享收件箱的邮件上设置不同的用户名 同时保留共享电子邮箱地址 这似乎无法通过 Office 365 运行 其工艺流程为 客户填
  • 使用scanf()时如何区分整数和字符

    我只是使用该功能scanf 代码如下 scanf d a printf d a 当我输入1时 它会像我想要的那样打印1 但即使我输入 1a 它也会像以前一样打印 1 当用户输入非整数时 例如 2 3 12ab 1 a 我想向用户显示 输入整
  • 线程安全的 C++ 堆栈

    我是 C 新手 正在编写一个多线程应用程序 不同的编写者将对象推入堆栈 读者将它们从堆栈中拉出 或至少将指针推入对象 C 中是否有任何内置结构可以在不添加锁定代码等的情况下处理此问题 如果没有 那么 Boost 库呢 EDIT 你好 感谢您
  • 如何在 C# 中使用 XmlDsigC14NTransform 类

    我正在尝试使用规范化 xml 节点System Security Cryptography Xml XMLDsigC14nTransformC net Framework 2 0 的类 该实例需要三种不同的输入类型 NodeList Str
  • 更改其他页面的主窗口内容

    在 WPF 应用程序的主窗口中 我有一个 Badged 元素 来自材料设计 这是我的代码
  • 将 bignum 类型结构转换为人类可读字符串的有效方法是什么?

    我有一点问题 为了增长我的 C 知识 我决定尝试实现一个基本的 bigint 库 bigint 结构的核心将是一个 32 位整数数组 选择它们是因为它们适合寄存器 这将允许我在数字之间进行操作 这些操作将在 64 位整数中溢出 这也将适合寄
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D
  • 使用剪贴板 SetText 换行

    如何使用 SetText 方法添加换行符 I tried Clipboard SetText eee n xxxx 但当我将剪贴板数据粘贴到记事本中时 它没有给我预期的结果 预期结果 eee xxxx 我怎样才能做到这一点 Windows

随机推荐

  • 使用 boost::asio::use_future 增强 asio:async_read()

    打电话时asio async read 使用 future 有没有办法获取当 a 时传输的字节数boost asio error eof出现异常 似乎在很多情况下 即使对等方断开连接 人们也希望传输数据 例如 namespace ba bo
  • 具有自定义背景图像的 Google 地图

    我希望找到一种方法来创建带有自定义背景图像的谷歌地图实例 我看过一些示例 下面链接 但没有找到任何有关如何执行此操作的文档 我希望有人能帮助我解决这个问题 Thanks 简单的例子 http www obsidianportal com c
  • 恢复/重置默认 Xcode 字体配色方案?

    所以我尝试单击 T 却不小心单击了 XCode 字体首选项中的 颜色 框 我已经处于 默认 状态 现在我正在尝试恢复它 我发现这是不可能的 我被其他程序中存在的 重置默认值 按钮宠坏了 除了重装还有什么办法吗 是的 我偏爱白色背景 随着时间
  • 什么时候适合使用C作为面向对象语言?

    关于如何使用 C 来模拟面向对象的概念 有很多优秀的答案 仅举几例 C 具有抽象数据类型的双链表 https stackoverflow com questions 3274472 c double linked list with abs
  • 设置animationDidStopSelector:在UIView的动画委托上

    我认为在过去一年半的 iPhone 开发经验中我一直在做这个错误 我需要一些知识渊博的澄清 您可能知道也可能不知道 使用 UIView 属性可以很容易地设置动画beginAnimations forContext 方法 并用一个包装它com
  • 如何使用正则表达式来匹配不包含多个特定单词之一的字符串?

    如何使用正则表达式来避免匹配包含多个特定单词之一的字符串 例如 字符串不应包含以下单词test nor sample sample test 我的正则表达式在某些情况下会失败 1 this is a test case 2 this is
  • 使用定义的模式生成多个动态 ID 的函数

    我正在尝试创建一个函数来生成具有定义模式的多个动态 ID 我该怎么做 跟进 Vue js 如何使用定义的模式生成多个动态 ID https stackoverflow com q 49776146 8770366 Details 我正在创建
  • 如何将 Chromium 嵌入式框架 (CEF) 与 java 集成

    我想制作一个桌面应用程序来浏览网站 我不想制作浏览器 而是制作浏览器嵌入应用程序 我尝试过JavaFx但我发现了一些问题 例如缺少对插件的支持 例如 flash pdf 查看器等 经过大量搜索后 我发现了 Chromium Embedded
  • XML:如何将一个 xml 文件的内容加载到另一个文件中

    我只是希望能够从另一个 xml 文件动态写入 xml 文件的内容 A XML包含
  • Angular 6 中 ng2-file-upload 的进度条

    我想为我的文件上传创建一个进度条 我使用的上传是 https www npmjs com package ng2 file upload https www npmjs com package ng2 file upload 应用程序组件
  • 导航抽屉项目未注册点击事件

    我正在努力让导航抽屉项目注册并启动并意图进行新活动 抽屉打开正常并正确显示 但当我单击列表中的项目时没有任何反应 这是我的代码 取自谷歌教程 mTitle mDrawerTitle getTitle mTitles getResources
  • 快速将大型 2d 矩阵融合为 3 列 data.table

    我有一个大矩阵num 1 62410 1 48010 我想要一个长格式的 data table e g Var1 Var2 value 1 1 1 4227 786 2 2 1 4211 908 3 3 1 4197 034 4 4 1 4
  • Javascript 按空格分隔,但不按引号分隔

    目标是在空格处分割字符串 但不分割引号中的文本数据或将其与相邻文本分开 输入实际上是一个包含值对列表的字符串 如果 value 值包含空格 则将其括在引号中 我需要一个返回值对元素数组的函数 如下例所示 输入示例 a 0 b 1 moo f
  • 使用 UCLIBC 交叉编译 PHP

    这是一个转发 之前的帖子已关闭 移至 SERVERFAULT 并再次关闭 我认为这篇文章是一个有效的堆栈溢出问题 因为我认为它是由一些 automake 编译 链接错误引起的 这是一个编程问题而不是服务器管理问题 我会检查 uClibc 的
  • Monogame:WAV 无法播放

    这是 MonoGame 3 4 我通过 VS2013 使用它 我正在使用 mgcb 编译我的 WAV 文件 就像我的纹理一样 MGCB 工作正常 但是当涉及到使用SoundEffect类 它不播放任何内容 没有例外并且SoundEffect
  • CKEDITOR,在文本编辑器 onLoad 上自动聚焦

    有人知道如何在页面加载时自动聚焦于 CKEDITOR 文本区域吗 目前 用户必须先单击文本区域才能开始输入 像 Google 一样 我希望加载页面 并且用户可以立即开始输入 而无需单击文本区域 这是启动 CKEDITOR 的当前代码
  • webRTC - 视频导致互联网上的通话中断

    更新1 我尝试像这样改变视频约束 var mediaConstraints audio true We want an audio track video width min 160 ideal 320 max 640 height min
  • 浏览器使用哪种等宽字体?

    对于 CSS 如果您指定font family monospace 我的理解是浏览器选择其默认 首选等宽字体 如果这是正确的 您如何确定您的浏览器正在使用哪种等宽字体 可以使用 5 个通用系列 serif sans serif cursiv
  • 在 Notepad++ 中显示不匹配的 html 标签

    有没有办法在 Notepad 中突出显示不匹配的 HTML 标签 例如 如果我有以下 HTML 我想要标签以某种方式突出显
  • 由于一个或多个外键属性不可为空,因此无法更改该关系

    使用 EF 更新期间出现以下错误 操作失败 无法更改关系 因为一个或多个外键属性不可为空 当关系发生更改时 相关的外键属性将设置为空值 如果外键不支持空值 则必须定义新关系 必须为外键属性分配另一个非空值 或者必须删除不相关的对象 有没有g