EF一对一关系改变实体与另一个(替代)

时间:2014-12-23 07:34:21

标签: c# .net entity-framework

我有问题将实体一对一更改为另一个:

这是我的测试类:

public class MyUser
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public virtual MyAddress MyAddress { get; set; }
}

public class MyAddress
{
    public Guid Id { get; set; }
    public string AddressLine { get; set; }
    public virtual MyUser MyUser { get; set; }
}

这是我的映射:

modelBuilder.Entity<MyAddress>().HasOptional(x => x.MyUser).WithRequired(x => x.MyAddress);

在DB中我有

MyUser ID = "abc", Name = "Test"
MyAddress ID = "abc", AddressLine = "TestAddress"
MyAddress ID = "dfg", AddressLine = "TestAddress2"

不,我想从MyUser中删除具有相同ID的MyAddress,并向MyUser添加具有其他ID的MyAddress

// myUser.Id = "abc" myUser.MyAddress.Id = "abc"
// myOldAddress.Id = "abc" myOldAddress.MyUser.Id = "abc"
// myNewAddress.Id = "dfg" myNewAddress.MyUser = null
var myUser = repoUser.GetById("abc")
var myOldAddress = repoAddress.GetById("abc");
myOldAddress.MyUser = null;
var myNewAddress = repoAddress.GetById("dfg");
myUser.MyAddress = myNewAddress;
myNewAddress.MyUser = myUser;
//on save I have this exception and what result i want to have
// myUser.Id = "abc" myUser.MyAddress.Id = "abc"
// myOldAddress.Id = "hjk" myOldAddress.MyUser = null
// myNewAddress.Id = "abc" myNewAddress.MyUser.Id = "abc"
// something like this (substitute)

Exception:
Additional information: A referential integrity constraint violation occurred: 
A primary key property that is a part of referential integrity constraint cannot be 
changed when the dependent object is Unchanged unless it is being set to the
 association's principal object. The principal object must be tracked and not
 marked for deletion.

{"A referential integrity constraint violation occurred: A primary key property
 that is a part of referential integrity constraint cannot be changed when the 
dependent object is Unchanged unless it is being set to the association's 
principal object. The principal object must be tracked and not marked for deletion."}

为什么EF不会自动更改ID与UserId相同?用户必须具有地址1:1,但地址具有可选的用户1:0

2 个答案:

答案 0 :(得分:3)

  

首先,我不相信用户之间的关系设计   和地址是一对一的,既不允许没有用户的地址   而不允许没有地址的用户。因为通常典型的用户可以有很多地址


但是,根据我们在评论部分的讨论,我得到了以下内容:

数据库中的地址表有2列: ID 不允许空AddressLine

因此,当您在代码中调用myOldAddress.MyUser = null;时 您只需将EF设置为数据库中的Address.Idnull,这违反了数据库约束

我不推荐的一个解决方案Address.Id允许null

但我建议将设计更改为以下之一:

  • 使用UserId以外的单独唯一键标识您的地址表
  • 创建一个列以保存相关的userId并使其允许为空

所以你的地址表如下:

ID (not null)
AddressLine 
UserId (Nullable) forieng key in User Table

这样您就可以安全地在代码中将MyAddress.MyUser设置为null

答案 1 :(得分:0)

从代码示例中,当前未设置myOldAddress.MyUser属性。你能尝试评论那条线吗

var myUser = repoUser.GetById("abc")
var myOldAddress = repoAddress.GetById("abc");
//myOldAddress.MyUser = null;
var myNewAddress = repoAddress.GetById("dfg");
myUser.MyAddress = myNewAddress;

由于用户字段在地址实体上是可选的,如果之前没有设置,则无需将其设置为空。