将子实体移动到新的父实体

本文关键字:实体 移动 | 更新日期: 2023-09-27 18:25:15

将子实体从父实体移动到另一个父实体的最佳方式是什么?ObjectContext或DbContext中是否有一种方法可以让我们实现这一点?

public class Person
{
   public int PersonId
   public ICollection<Car> Cars
}
public class Car
{
   public int CarId
   public string Color
}

编辑:我目前正在使用EF 4.0模型首先与POCO模板。

将子实体移动到新的父实体

我想说,在本例中,您想要实现的是更换车主。如果在Car中添加对Person的反向引用没有严重的缺点,我会选择以下内容:

public class Car
{
   ...
   public virtual Person Owner { get; protected set; }
   public void ChangeOwner(Person newOwner)
   {
          // perform validation and then 
          Owner = newOwner;
          // maybe perform some further domain-specific logic
   }
}

注意:受保护的setter用于强制外部使用者调用ChangeOwner方法。EF将能够正确设置它,这要归功于POCO类的自动生成代理(假设您使用它们)。

编辑:如果不可能添加对Person的反向引用,那么从域逻辑的角度来看,您仍然有相同的目标。你只想换个车主。这样的操作涉及两个实体,所以我可能会选择一个放置在实体外部的方法(不管它应该放在设计良好的系统中的哪里):

public void ChangeCarOwner(Person originalOwner, Person newOwner, int carId)
{
    Car car = originalOwner.RemoveCarOwnership(carId);
    newOwner.AddCarOwnership(car);
}
public class Person
{
    ...
    public Car RemoveCarOwnership(int carId)
    {
        Car car = this.Cars.Single(c => c.Id == carId);
        this.Cars.Remove(car);
        return car;
    }
}

这只是一段概念性的代码,当然它可以写得更好(确保老车主真的拥有这辆车等等),但我只是想提出一个如何处理它的想法。我也放弃了AddCarOwnership的实现,因为我认为它很有局限性。我介绍了这些方法,因为添加和删除所有权可能会在特定的人"内部"触发一些进一步的逻辑。

使用现代EFCore,您可以通过附加新的Parent实体来实现这一点,该实体包含具有ID的子实体。它将重新分配子对象的FK(或者在没有指定ID的情况下创建它),并创建新的Person,所有这些都是一次性

例如:

var newOwner = new Person { 
    Cars = new List<Car> { 
        new Car { carId = theCarToMove.carId } 
    } 
};
Context.Attach(newOwner);
await Context.SaveChangesAsync();

注意,如果您的上下文不是真正的瞬态,那么Attach可能会导致问题,但作为一个创可贴,您可以在尝试Attach 之前清除ChangeTracker

编辑:经过尝试,我发现对于一些数据库提供商来说,它不能直接工作。相反,请尝试:

foreach(var car in carsToMove)
{
    Context.Attach(car);
    car.Owner = newOwner;
}
Context.Attach(newOwner);
await Context.SaveChangesAsync();

使用Attach时,顺序很重要。EFCore构建的SQL查询的构建顺序与您在C#中设置它的顺序相反。如果在cars之前附加newOwner,那么CREATE查询是SQL中的最后一个查询,在cars的UPDATE之后。如果是这种情况,汽车就不能更新到新的OwnerId,因为newOwner在查询中当时没有ID。我相信这也是第一个代码块的情况,一些提供程序