使用现有嵌套实体保存新的已断开连接的实体,而不复制现有实体

本文关键字:实体 连接 复制 断开 嵌套 保存 | 更新日期: 2023-09-27 18:12:01

这是我的模型:

public class Place
{
    public int ID { get; set; }
    public virtual ICollection<AddressLine> AddressLines { get; set; }
}
public class AddressLine
{
    public int ID { get; set; }
    public int Order { get; set; }
    public string Value { get; set; }
    public virtual Place Place { get; set; }
    public virtual ICollection<AddressLineType> AddressLineTypes { get; set; }  
}
public class AddressLineType
{
    public int ID { get; set; }
    public string Value { get; set; }
    public virtual ICollection<AddressLine> AddressLines { get; set; }
}

当用EF6创建一个新的Place实体时,我必须使用一个分离的实体,没有办法绕过它,我可以通过传递对上下文的引用来看到。

我的问题是,PlaceAddressLine是新的,但AddressLineType已经存在。

当我尝试保存Place实体时,即使设置了AddressLineType ID属性,因为它是分离的,EF将把它作为新的插入,从而复制现有的AddressLineType条目。

我已经做了一些研究,试图绕过它,并找到了一篇文章,建议最好的方法是将AddressLineType添加为null并设置外键属性,这将给出所需的行为。这个例子是一对多关系,但我不知道如何在这里为多对多关系做这个。

我只是使用实体框架的命名约定来理解映射(我真的不怎么接触数据库)。当我做一对多关系时,我可以看到它会自动添加外键但这在多对多关系中是如何工作的呢?

理想情况下,我希望这个问题在创建Place的代码中进行排序,但我尝试在保存代码中执行以下操作。它不会添加重复数据,但会抛出异常,因为AddressLineTypes已经存在。

foreach( var v in place.AddressLines)
{
    foreach (var v2 in v.AddressLineTypes)
    {
        db.AddressLineTypes.Attach(v2);
    }
}

在将断开连接的实体添加到上下文并保存之前,我如何显示该实体中的关系?

使用现有嵌套实体保存新的已断开连接的实体,而不复制现有实体

您需要手动修改断开连接实体的状态,以便像这样更新记录-

    foreach( var v in place.AddressLines)
    {
        foreach (var v2 in v.AddressLineTypes)
        {
            db.Entry<AddressLineTypes>(v2).State = EntityState.Modified;
        }        
    }

表示要添加的实体有对其他实体的引用如果还没有被跟踪,那么这些新的实体也会被添加到上下文,并将在下次调用时插入到数据库中SaveChanges被调用。

https://msdn.microsoft.com/en-in/data/jj592676.aspx