我有问题将实体一对一更改为另一个:
这是我的测试类:
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
答案 0 :(得分:3)
首先,我不相信用户之间的关系设计 和地址是一对一的,既不允许没有用户的地址 而不允许没有地址的用户。因为通常典型的用户可以有很多地址
但是,根据我们在评论部分的讨论,我得到了以下内容:
数据库中的地址表有2列:
ID
不允许空和AddressLine
因此,当您在代码中调用myOldAddress.MyUser = null;
时
您只需将EF设置为数据库中的Address.Id
到null
,这违反了数据库约束
我不推荐的一个解决方案让Address.Id
允许null
但我建议将设计更改为以下之一:
所以你的地址表如下:
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;
由于用户字段在地址实体上是可选的,如果之前没有设置,则无需将其设置为空。