实体框架 - 在种子方法中将现有实体添加到一对一关系

3

我的领域类:

public class Address
{
    [Key]
    public virtual string AddressId { get; set; }

    public virtual Site Site { get; set; }
}

public class Site
{
    [Key]
    public virtual int SiteId { get; set; }

    public virtual Address Address { get; set; }
}

使用Fluent API进行映射:

public class SiteMappings : EntityTypeConfiguration<Site>
{
    public SiteMappings()
    {
        HasRequired(s => s.Address)
        .WithOptional(a => a.Site)
        .Map(s => s.MapKey("AddressId"))
        .WillCascadeOnDelete(false);
    }
}

种子方法:

var addresses = new List<Address>
{
    new Address { AddressId = "1" }
};
addresses.ForEach(s => context.Addresses.AddOrUpdate(p => p.AddressId, s));

var sites = new List<Site>
{
    new Site { SiteId = 1, Address = addresses.Single(s => s.AddressId.Equals("1"))}
};
sites.ForEach(s => context.Sites.AddOrUpdate(p => p.SiteId, s));

错误:

Violation of PRIMARY KEY constraint 'PK_dbo.Addresses'. Cannot insert duplicate key in object 'dbo.Addresses'. The duplicate key value is (1)

当我尝试添加新的“站点”时,似乎也插入了新的“地址”。如何避免这种情况?如何在我之前添加到DBcontext中插入现有的“地址”? 我对Entity Framework不熟悉,非常感谢您的帮助。 提前致谢!


你好,我遇到了类似的问题。我有相似的类,并且正在尝试使用Model2下拉列表中选择的选项保存Model1。我的错误是“'Mydbcontext'中的实体参与'model1_model2'关系。找到0个相关的'model1_model2_Target'。期望1个'model1_model2_Target'”,这是一对一的关系。 - guitarlass
1
我通过插入由当前上下文管理的“地址”来解决了这个问题。new Site { SiteId = 1, Address = context.Addresses.FirstOrDefault(a => a.AddressId.Equals("1"))} - Para Kan
2个回答

2
在将地址指定给站点实例后,对于每个地址实例,请使用以下内容:
context.Entry(existingAddress).State = EntityState.Unchanged;

这将把地址的状态设置为未更改,而不是已添加,EF将不会尝试再次添加它们。

此外,在添加地址的ForEach之后尝试调用context.SaveChanges()


Attaching an entity of type 'TransportManagementSystem.Models.Address' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate. - Para Kan
看一下我上面的编辑。顺便问一下,为什么你的AddressId是一个字符串而不是一个int,因为你给它赋了一个值1?这是一个错误还是故意的设计? - Liviu Mandras
我尝试了以下代码:addresses.ForEach(s => context.Addresses.AddOrUpdate(p => p.AddressId, s)); context.SaveChanges(); var sites = new List { new Site { SiteId = 1, Address = addresses.Single(s => s.AddressId.Equals("1"))} }; sites.ForEach(s => context.Sites.AddOrUpdate(p => p.SiteId, s)); context.Entry(addresses.Single(s => s.AddressId.Equals("1"))).State = EntityState.Unchanged; context.SaveChanges();出现错误:有多个类型为“TransportManagementSystem.Models.Address”的实体具有相同的主键值 - Para Kan

1
我通过插入当前上下文管理的“地址”来解决了这个问题。
new Site { SiteId = 1, Address = context.Addresses.FirstOrDefault(a => a.AddressId.Equals("1"))}

以下代码将利用当前上下文中现有的“地址”而不是尝试插入新的“地址”。
context.Addresses.FirstOrDefault(a => a.AddressId.Equals("1"))}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接