很抱歉再次举起这个 - 我在这里看到了很多次但我仍然对我的情况感到困惑,特别是因为我似乎能够克服'它,但我不确定我喜欢怎么做,我很想知道为什么。
我在Staff和Departments之间有很多关系,StaffDepartment表设置了一个复合键,如下所示:
modelBuilder.Entity<StaffDepartment>()
.HasKey(sd => new { sd.StaffId, sd.DepartmentId });
我怀疑这必须与我有时会得到的例外有关:
InvalidOperationException: The instance of entity type 'StaffDepartment' cannot be tracked because another instance with the same key value for {'StaffId', 'DepartmentId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
我有时会说,因为,奇怪的是,如果我更改了员工详细信息页面中的部门并进行了更新,那么它会很顺利,但是当我保留它时(例如,可能只是更改员工姓名)我会收到此异常。
我尝试对此实施各种建议 similar but apparently different SO discussion 以及各种修改我的存储库更新方法的方法,奇怪的是,这是我使用它的唯一方法:
public async Task UpdateStaff(StaffDto staff)
{
var staffToUpdate = await _db.Staff
.Include(d => d.Departments)
.ThenInclude(d => d.Department)
.SingleOrDefaultAsync(s => s.Id == staff.Id);
// Without either these two line I get the exception
_db.StaffDepartment.RemoveRange(staffToUpdate.Departments);
await _db.SaveChangesAsync();
_mapper.Map(staff, staffToUpdate);
await _db.SaveChangesAsync();
}
所以我应该用同样的方法两次调用SaveChangesAsync()
似乎很奇怪。那里到底发生了什么?如果不这样做,我将如何在错误When attaching existing entities, ensure that only one entity instance with a given key value is attached
中实现建议。
实体类看起来像这样:
public class Staff
{
public int Id { get; set; }
...
public ICollection<StaffDepartment> Departments { get; set; }
}
public class Department
{
public int DepartmentId { get; set; }
...
public ICollection<StaffDepartment> Staff { get; set; }
}
public class StaffDepartment
{
public int StaffId { get; set; }
public Staff Staff { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }
}
从域名等回来的staffDto就是:
public class StaffDto
{
public int Id { get; set; }
...
public List<DepartmentDto> Departments { get; set; }
}
存储库全部注册为瞬态,即
services.AddTransient<ICPDRepository, CPDRepository>();