在 EF 中调用 SaveChanges() 后将获取的旧记录保留在变量中

Posted

技术标签:

【中文标题】在 EF 中调用 SaveChanges() 后将获取的旧记录保留在变量中【英文标题】:Retain fetched old record in a variable after SaveChanges() are called in EF 【发布时间】:2015-04-27 06:46:16 【问题描述】:

我编写了一个函数,用于更新员工的详细信息。 在每次成功更新时,我都必须将 Employee 的旧记录记录到历史记录表中。

所以我需要将旧记录保留在内存变量中,然后一旦 SaveChanges() 成功完成,我必须将它传递给 LogHistory(),它接受一个 Employee 对象并将旧员工记录的条目添加到 Employee_History表。

问题:

在下面的代码中,一旦调用 SaveChanges(),变量 oldEmployee 也会更新并添加更新后的员工记录,而不是添加旧员工的详细信息。

public void UpdateEmployee(int employeeID, Employee personalInfo)
        
            var employee = context.Employees.FirstOrDefault(clnt => clnt.PK_EmployeeID == employeeID);
            var oldEmployee = context.Employees.FirstOrDefault(clnt => clnt.PK_EmployeeID == employeeID);
            if (employee != null)
            
                employee.FirstName = personalInfo.FirstName;
                employee.LastName = personalInfo.LastName;

                //Update Client details
                context.SaveChanges();

                //Logging History for previous Client details
                context.LogTransaction(oldEmployee);
            
        

请建议并帮助我克服这种情况。

【问题讨论】:

【参考方案1】:

变量employeeoldEmployee 都指向同一个引用,即您要更新和保存的员工。您必须在修改之前创建 employee 的副本并将其提交到日志记录。

您可以通过多种方式创建副本。其中之一是使用CurrentValues

var oldEmployee = context.Entry(employee).CurrentValues.ToObject();

或者简单地创建一个新员工并复制属性。

【讨论】:

我正在使用 ObjectContext api,它的 CurrentValues 没有 .ToObject()。 啊。好吧,这只是创建副本的一种方式。您可以选择任何其他可用的克隆模式。要点是您必须创建一个副本。您甚至可以考虑将您的应用程序重构为 DbContext API,这有很多好处。 是的,正在寻找克隆模式,但似乎没有找到适合我的模式。 你知道2分钟后提到它吗?无论如何,克隆方法超出了这个问题的范围。如果您需要更具体的帮助,请随时提出新问题。

以上是关于在 EF 中调用 SaveChanges() 后将获取的旧记录保留在变量中的主要内容,如果未能解决你的问题,请参考以下文章

ef的savechanges最多执行多少条数据

ef保存文件到指定目录

EF Core 3 的 DbContextScope 模式

何时在 EF 6 中使用 BeginTransaction? vs SaveChanges [重复]

如何在 .SaveChanges() 期间首先使用 EF 代码记录所有实体更改?

使用 EFCore.BulkExtensions 时是不是需要调用 SaveChanges