Reputation: 1730
I have problem to change entity one to one with another:
Here is my test classes:
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; }
}
Here is my mapping:
modelBuilder.Entity<MyAddress>().HasOptional(x => x.MyUser).WithRequired(x => x.MyAddress);
In DB i have
MyUser ID = "abc", Name = "Test"
MyAddress ID = "abc", AddressLine = "TestAddress"
MyAddress ID = "dfg", AddressLine = "TestAddress2"
No I want to remove from MyAddress from MyUser where they have same ID, and to add to MyUser a MyAddress that has other ID
// 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."}
Why EF doesn't change ID automatically to be the same as UserId? User must have Address 1:1, but Address has optional User 1:0
Upvotes: 2
Views: 4789
Reputation: 869
First, I am not convinced with the design where relation between User and Address is one-to-one, neither allowing addresses without users while not allowing users without addresses. Because usually a typical user can has many addresses
However, as per our discussion in the comments section, I got the following:
Your Address table in database has 2 columns:
ID
that does not allow null and AddressLine
So, when you call myOldAddress.MyUser = null;
in your code
You simply till EF to set Address.Id
to null
in database which violate the DB constraint
One solution, that I don't recommend is to let Address.Id
to allow null
But I recommend to change the design to one of the following:
So your Address table will be as follows:
ID (not null)
AddressLine
UserId (Nullable) forieng key in User Table
This way you can set MyAddress.MyUser
to null
in your code, safely
Upvotes: 3
Reputation: 439
From the code samples, myOldAddress.MyUser property is currently not set. Can you try commenting that line out
var myUser = repoUser.GetById("abc")
var myOldAddress = repoAddress.GetById("abc");
//myOldAddress.MyUser = null;
var myNewAddress = repoAddress.GetById("dfg");
myUser.MyAddress = myNewAddress;
Since user field is optional on the address entity, if you did not set it before, there is no need to set it to null.
Upvotes: 0