对 EF 中的跟踪感到困惑(使用子集合更新实体)

2024-03-15

所以我是 EF 新手(我正在使用 EF6),并且我在理解这个概念时遇到问题,我正在尝试使用子集合更新实体。

这是我的实体类:

public class TimeSheet
{
    public int TimeSheetID { get; set; }
    public virtual ICollection<TimeSheetDetail> Details { get; set; }
}

public class TimeSheetDetail
{
    public int TimeSheetDetailID { get; set; }
    public int TimeSheetID { get; set; }
    public virtual TimeSheet TimeSheet { get; set; }
}

我的更新方法:

public void Update(TimeSheet obj)
{
    var objFromDB = Get(obj.TimeSheetID);
    var deletedDetails = objFromDB.Details.Except(obj.Details).ToList();

    _dbContext.Entry(obj).State = EntityState.Modified;

    //track if details exist
    foreach (var details in obj.Details)
    {
        _dbContext.Entry(details).State = details.TimeSheetDetailID == 0 ? EntityState.Added : EntityState.Modified;
    }

    //track deleted item
    foreach (var deleted in deletedDetails)
    {
        _dbContext.Entry(deleted).State = EntityState.Deleted;
    }
}

public TimeSheet Get(object id)
{
    //return _timeSheet.Find(id); //Without AsNoTracking I got error
    int x = Convert.ToInt32(id);
    return _timeSheet.AsNoTracking().SingleOrDefault(a => a.TimeSheetID == x);
}

上面的代码给我Attaching an entity of type 'ClassName' failed because another entity of the same type already has the same primary key value。所以我的问题是:

  1. 如何使用 EF 更新子集合?意味着如果数据库中不存在我需要添加新的,否则更新,或者如果它在数据库中删除则从数据库中删除POST.

  2. 如果我不使用AsNoTracking(),它会抛出Saving or accepting changes failed because more than one entity of type 'ClassName' have the same primary key value。我注意到该错误是由我造成的DbSet将数据库中的数据添加到其Local如果我不使用财产AsNoTracking()这会导致 EF 框架抛出错误,因为它认为我有重复的数据。这实际上是如何运作的?

  3. 正如你所看到的,我正在尝试比较objFromDb反对obj检查用户是否删除了其中一项详细信息,以便我可以将其从数据库中删除。相反,我得到了一堆DynamicProxies从采集结果来看。什么是DynamicProxies它是如何运作的?

  4. 有没有关于 EF 的好文章或 101 教程?到目前为止,我只看到一个简单的答案,这对我的情况没有帮助,我环顾四周,找到了如何做事情的混合答案。老实说,此时我希望我只使用经典的 ADO.Net 而不是 EF。


为了更好地理解实体框架,请考虑DbContext作为应用程序和数据库之间的代理。 这DbContext将缓存所有内容并使用缓存值中的所有数据,除非您告诉它不要这样做。

For 1.:这取决于您的环境,如果您DbContext不在选择和更新实体之间进行处理,您可以简单地调用SaveChanges并且您的数据将被保存。如果你的DbContext处理完毕后,您可以将实体从上下文中分离出来,更改数据,重新附加它们并设置EntityState来修改。

我无法给你100%肯定的答案,因为我大约半年前就停止使用实体框架了。但我知道更新复杂的关系是一件痛苦的事。

For 2.: 命令AsNoTracking告诉 EF 不要跟踪对此查询内的实体所做的更改。例如,您从数据库中选择 5 个时间表,更改第一个实体中的一些值并删除最后一个实体。这DbContext知道第一个实体已更改,最后一个实体已删除,如果您调用SaveChanges the DbContext将自动更新第一个实体,删除最后一个实体,并保持其他实体不变。现在,您尝试自己更新实体并将第一个实体再次附加到 DbContext。

DbContext 现在将有两个具有相同键的实体,这会导致异常。

For 3.: The DynamicProxies是实体框架用来跟踪这些实体的变化的对象。

For 4.:检查这个link http://www.entityframeworktutorial.net/,还有一本关于实体框架6的好书(书名:《编程实体框架》)

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

对 EF 中的跟踪感到困惑(使用子集合更新实体) 的相关文章

  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐