首页 > 解决方案 > 工作单元更新问题:实体已经在跟踪另一个实例

问题描述

我的UOW 模式实现有问题(我的 UOW 使用存储库模式)。我将尝试用两个简单的课程来解释我的项目结构。我有人和汽车,(一对多 - 一对一)。

[Table("Person")]
public class Person
{
    public int id{ get; set; }
    public string name{ get; set; }
    public IList<Car> cars_owned{ get; set; }

}

[Table("Car")]
public class Car
{
    public int id{ get; set; }
    public Person owner{ get; set; }
}

在我的 CarServiceImplementation 中,我想实现我的AddUpdateCar()以便添加一个“Person”(如果它不存在或更新它)。

这是我的实际实现:

public async Task<bool> addUpdateCar(AddUpdateCarModel model)
        {
            var car = await unitOfWork.CarRepository.GetByID(model.car_id);
            var person = await unitOfWork.PersonRepository.GetByID(model.person.id);
            if (person == null)
            {
                unitOfWork.PersonRepository.Insert(model.person);
            }
            else
            {
                unitOfWork.PersonRepository.Update(model.person);
            }

            car.owner = model.person;
            unitOfWork.CarRepository.Update(car);
            unitOfWork.Save();
            return true;
        }

这种 impl 表示:无法跟踪实体类型“Person”的实例,因为已经在跟踪具有相同键值 {'id'} 的另一个实例。

我也尝试了不同的方法,但我还有其他问题。

哪个是实现此方法的正确方法?

编辑1:

public void Update(Person p)
{
    context.Entry(p).State = EntityState.Modified;
}

public async Task<Person> GetByID(int id)
        {
            return await context.person.FindAsync(id);
        }

标签: c#entity-framework-5unit-of-work

解决方案


由于您使用的是工作单元,因此最简单的方法是向 PersonRepository 添加一个新方法

public void InsertOrUpdate(Person p)
{
    var existedPerson = GetByID(p.id);
    if (existedPerson != null) 
        context.Entry(existedPerson).CurrentValues.SetValues(p);
    else Insert(p);
}

推荐阅读