【问题标题】:Why is Entity Framework (Core) deleting old records on Add() operation?为什么实体框架(核心)在 Add() 操作中删除旧记录?
【发布时间】:2016-12-08 21:23:52
【问题描述】:

我有一个实体,需要在其上跟踪员工工资率的历史记录。 employeeRate 对象是:

public class EmployeeRate : BaseEntity
{
    [Key]
    public int EmployeeRateId { get; set; }

    public int EmployeeId { get; set; }

    public double Rate { get; set; }
}

public class BaseEntity
{
    public bool ActiveFlag { get; set; }

    public DateTime CreateStamp { get; set; }

    public DateTime UpdateStamp { get; set; }

    public string LastModifiedBy { get; set; }
}

因此,为了跟踪历史记录,当我“更新”员工费率时,我会检索所有带有其 Id 的旧记录并将 ActiveFlag 设置为 false,然后添加一个具有新工资率的新实体,并将 ActiveFlag 设置为 true。这是我执行此操作的函数:

private EmployeeRate UpdateRate(EmployeeRate model, string currentUser)
{
    var existingRates = _context.EmployeeRates.Where(r => r.EmployeeId == model.EmployeeId).ToList();
    foreach(var rate in existingRates)
    {
        rate.ActiveFlag = false;
        rate.UpdateStamp = DateTime.UtcNow;
        rate.LastModifiedBy = currentUser;
    }
    _context.SaveChanges();

    var newRate = new EmployeeRate()
    {
        EmployeeId = model.EmployeeId,
        Rate = model.Rate,
        ActiveFlag = true,
        CreateStamp = DateTime.UtcNow,
        UpdateStamp = DateTime.UtcNow,
        LastModifiedBy = currentUser
    };

    newRate = _context.EmployeeRates.Add(newRate).Entity;
    _context.SaveChanges();

    return newRate;
} 

当我对我的 DbContext 对象执行添加操作时,EntityFramework 生成的 SQL 出于某种原因正在删除该员工的所有旧记录。
生成的 SQL:

employeerates 删除EmployeeRateId = @p0;

插入 employeerates (ActiveFlag, CreateStamp, EmployeeId, LastModifiedBy, Rate, UpdateStamp) 值 (@p1, @p2, @p3, @p4, @p5, @p6);选择 EmployeeRateIdemployeerates 哪里 ROW_COUNT() = 1 AND EmployeeRateId=LAST_INSERT_ID();

为什么会发生这种情况?有没有办法让 EF 不删除这些旧记录?

编辑

我正在使用 asp.net 核心和实体框架核心。

【问题讨论】:

  • 我不明白newRate = _context.EmployeeRates.Add(newRate).Entity;这行...其他一切看起来都很好。 BaseEntity 长什么样子?
  • 你在这里做两次SaveChanges有什么原因吗?
  • @Marc 我为 BaseEntity 编辑了我的帖子。抱歉,为了之前的帖子,我尝试对其进行简化,但使它更加混乱;)有问题的代码行只是将 newRate 对象添加到 EmployeeRates DbSet,然后将返回的实体分配回新的费率,以便调用 _context.SaveChanges() 时会填充生成的 Id
  • @stephen.vakil,我认为由于某种原因,如果在运行 Add 之前没有提交更新操作,可能会导致 SQL 问题。然而,我证明这是错误的,因为我在整个更新部分注释掉的情况下运行它,我得到了相同的结果
  • 所有,我认为在两个不同的行中有两个相同的“EmployeeId”值可能是个问题。如果我手动将几条记录添加到与我添加的 EmployeeId 相同的数据库中,它将删除所有记录。这很奇怪,因为生成的 SQL 是根据“EmployeeRateId”删除的

标签: c# entity-framework asp.net-core entity-framework-core


【解决方案1】:

准备骂我笨蛋……

由于我想跟踪 EmployeeRate 对象的历史记录,我错误地考虑了 Employee 和 EmployeeRate 之间的关系。这是我最初的 Employee 对象(我本来应该发布的):

    public class Employee : BaseEntity
    {
        public int EmployeeId { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string Email { get; set; }

        public string PhoneNumber { get; set; }

        public int HomeLocationId { get; set; }




        //Navigation Properties
        public virtual Location HomeLocation { get; set; }

        public virtual EmployeeRate EmployeeRate { get; set; }
    }

你们中的一些人可能会马上看到这里的问题。 EmployeeRate 引用实际上必须是这样的:

public virtual List<EmployeeRate> EmployeeRates { get; set; }

因为它实际上是一对多的关系。由于我认为每个员工只需要一个费率,我之前只有一个单一的参考(就 EF 而言,它是一对一的)。因此,当我更新引用时,EF 认为它是一对一的,因此它删除了具有相同引用的所有其他记录。它实际上是“一对多”,一次只有一个“活跃”率。因此 EmployeeRate 导航属性需要作为 List 或 Collection 来引用,EF 才能正常工作而不是删除旧记录。愚蠢的我;)

【讨论】:

  • 我也有类似的情况。我想添加两个具有相同 UserId 的实体,但我有一对一的关系。谢谢。
猜你喜欢
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多