更新 EF 6 中的现有数据会引发异常 - “...相同类型的实体已具有相同的主键值。”

2023-11-27

我正在尝试使用 Entity Framework 6、代码优先、没有流畅的映射或 Automapper 等工具来更新记录。

实体(Employee)具有与其相关的其他复合属性,例如Addreess(收藏),Department

它也继承自一个名为User

保存方法如下,其中_dbContextDbConext执行

        public bool UpdateEmployee(Employee employee)
        {
            var entity = _dbContext.Employees.Where(c => c.Id == employee.Id).AsQueryable().FirstOrDefault();
            if (entity == null)
            {
                _dbContext.Employees.Add(employee);
            }
            else
            {
                _dbContext.Entry(employee).State = EntityState.Modified; // <- Exception raised here
                _dbContext.Employees.Attach(employee);

            }

            return _dbContext.SaveChanges() > 0;

        }

我不断收到错误:

附加类型的实体失败,因为另一个相同的实体 type 已经具有相同的主键值。这可能发生在以下情况: 使用“附加”方法或将实体的状态设置为 如果图表中的任何实体有,则为“未更改”或“已修改” 冲突的关键值。这可能是因为有些实体是新的并且 尚未收到数据库生成的键值。在这种情况下使用 “添加”方法或“已添加”实体状态来跟踪图形和 然后将非新实体的状态设置为“未更改”或“已修改”,如下所示 合适的。

我已经尝试过以下方法:

  1. 设置为之前连接EntityState.Modified
  2. Adding AsNoTracking()查询对象是否存在(没有例外,但数据库未更新) -https://stackoverflow.com/a/23228001/919426
  3. 使用基础实体保存_dbContext.Users而不是 Employee 实体 -https://stackoverflow.com/a/25575634/919426

现在这些都不适合我。

我可能犯了什么错误,导致其中一些解决方案在我的情况下不起作用?


EF 已经包含了一种无需借助 Automapper 即可映射属性的方法,假设您没有导航属性更新:

public bool UpdateEmployee(Employee employee)
    {
        var entity = _dbContext.Employees.Where(c => c.Id == employee.Id).AsQueryable().FirstOrDefault();
        if (entity == null)
        {
            _dbContext.Employees.Add(employee);
        }
        else
        {
            _dbContext.Entry(entity).CurrentValues.SetValues(employee);              
        }

        return _dbContext.SaveChanges() > 0;

    }

这通常会生成更好的 SQL 语句,因为它只会更新已更改的属性。

如果你还想用原来的方法,就去掉entity从上下文来看,要么使用 AsNoTracking (不确定为什么它在你的情况下没有更新,它应该没有效果,所以问题可能是其他的),要么修改你的查询以防止它首先具体化实体,使用类似的东西bool exists = dbContext.Employees.Any(c => c.Id == employee.Id)例如。

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

更新 EF 6 中的现有数据会引发异常 - “...相同类型的实体已具有相同的主键值。” 的相关文章

  • 实体框架手动删除的表无法从 EF 迁移生成

    我已经创建了迁移并创建了数据库和表 例如 表格是 A B C D E 现在我再次更改了代码的某些部分并运行update database命令 一切都很顺利 很好 表格显示了列 现在我不小心手动删除了一张两张表D and E 现在 当我尝试运
  • 如何正确使用memcpy?

    我有一个mainbuf bufsize 最初为空 我正在阅读一些输入 read fd otherbuf sizeof otherbuf 分配给不同的字符串otherbuf 每次我分配一个新字符串给otherbuf我想将其附加到mainbuf
  • 使用 C# 将文件列表从 ftp 下载到本地文件夹? [复制]

    这个问题在这里已经有答案了 我希望将 ftp 中的所有文件下载到本地文件夹 下载到本地驱动器后 所有文件都应在 ftp 中删除 从下面的代码 我只能从 ftp 下载一个我不期望的文件 我需要将所有文件放在一个文件夹中 但不放在本地文件名的名
  • 什么是合适的 NHibernate / Iesi.Collections.Generic.ISet 替代品?

    在最新版本的 Iesi Collections 中缺少 Iesi Collections Generic ISet 似乎有三种选择 链接哈希集 只读集 同步集 Iesi Collections Generic ReadOnlySet 似乎最
  • 创建一个从用户机密获取连接字符串的 DbContextFactory

    使用 DotNetCore 解决方案WebApi项目和一个单独的Data包含实体框架实现的项目 我们一直在升级库 因此我们使用所有最新的核心内容 In the Data项目 我们创建了一个ApplicationDbContextFactor
  • 为什么要在 C 和 C++ 项目中创建 include/ 目录?

    当我处理我的个人 C 和 C 项目时 我通常把file h and file cpp在同一目录中 然后file cpp可以参考file h with a include file h 指示 然而 通常会发现库和其他类型的项目 如 linux
  • C# 中的 memcpy 函数 [重复]

    这个问题在这里已经有答案了 可能的重复 C memcpy 等效项 https stackoverflow com questions 510971 c memcpy equivalent 相当于什么memcpyC 中的函数 正如已经说过的
  • 带和不带指针声明符的 C++11 自动声明

    不同类型有什么区别bar1 and bar2 int foo 10 auto bar1 foo auto bar2 foo If both bar1 and bar2 are int 编写指针声明符是否有意义 在里面bar2宣言 这些声明完
  • iText7 RegexBasedLocationExtractionStrategy 如何获取找到的文本的字体名和字体大小

    我尝试在 C 上使用 iText7 进行文本替换 我只能使用 RegexBasedLocationExtractionStrategy 获取搜索文本的内容和矩形 并且我想获取文本的字体和大小 有什么建议么 谢谢 你可以实施IText提取策略
  • Linux 相当于 GetCommandLine 和 CommandLineToArgv?

    我想知道是否有一些 API 可以在 Linux 上获取当前进程的命令行参数 我想我是非常不清楚的 该问题的真正目的是通过命令行参数传递 unicode 文件名 从文件中读取 proc self cmdline 例如 wallyk zf od
  • 对双向链表进行排序 C++

    尝试通过遍历列表的循环来完成此操作 在循环中 我将头节点输入到我定义的排序函数中 然后使用 strcmp 来确定节点中的哪个名称是否应该排在前面 它不起作用 因为写得太早了 我通过一次沿着列表一个节点进行线性比较 而不是回去查看第一个节点是
  • 网页上的富文本编辑器

    我正在尝试在我的网页中添加一个富文本编辑器 用户可以在其中撰写评论并格式化他们所写的内容 类似于我们在此网站上撰写帖子的编辑器 谁能指出我关于此的正确方向 任何可以帮助我构建这样一个组件的教程 我还想要一个免费的产品 忘记之前提到 类似的东
  • 像 MS Excel 一样在 C++ 中舍入双精度值

    我在网上进行了搜索 但找不到解决我的问题的方法 我只是想要一个像 MS Excel 那样对双精度值进行舍入的函数 这是我的代码 include
  • Doxygen 支持 C++11 模板别名(“using”语法)吗?

    我正在使用 doxygen 1 7 1 为一些 C 11 代码生成文档 它似乎忽略了我的模板别名 为了清楚起见 下面是模板别名的示例 template
  • 使用 C# winforms 与 Windows 中的其他桌面应用程序交互

    我想知道是否可以与使用我的程序的其他程序进行交互 例如 单击另一个程序上的按钮等 我不确定这是否可能 但如果可能的话 有人可以提供一些 C 示例代码 Thanks 您可以创建消息并将其发送到其他进程 为此 您必须在 C 代码中使用 P In
  • 如何在控制台应用程序中创建事件循环/消息管道?

    我想创建一个注册了一些事件的控制台应用程序 问题是这些事件永远不会被触发 在这种特殊情况下Windows 窗体 http en wikipedia org wiki Windows Forms我应该调用的应用程序Application Ru
  • 如何获取字典元素的相对位置?

    我有下一个 C 代码 Dictionary
  • 我使用 difftime 的 c 函数有时会返回 65535

    我有一个函数 使用 difftime 来检测自通信心跳停止以来的时间 以秒为单位 该函数的运行速度可以达到每 50 毫秒一次 该函数似乎可以工作 除了偶尔返回 65535 之外 我可以将执行次数减少到每秒一次 因为 difftime 的返回
  • 在 Outlook 中检索当前电子邮件正文

    在我的 Outlook 插件中 我想在功能区上添加一个按钮 因此当用户单击此按钮时 我想检索当前选定的电子邮件的正文 我有此代码 但它只检索收件箱中的第一封电子邮件 因为索引为 1 Microsoft Office Interop Outl
  • Xamarin - iOS 地图上的多个多边形

    我目前正在关注this https developer xamarin com guides xamarin forms application fundamentals custom renderer map polygon map ov

随机推荐