Using Entity Framework Core in ASP.NET - I decided to encapsulate all the Address information into a class with the [Owned](https://learn.microsoft.com/en-us/ef/core/modeling/owned-entities) attribute:
[Microsoft.EntityFrameworkCore.Owned]
public class Address
{
public string? Street { get; set; }
public string? City { get; set; }
public string? Zipcode { get; set; }
...
public void UpdateInfo(string? street, string? city, string? zipcode)
{
this.Street = street;
this.City = city;
this.Zipcode = zipcode;
}
}
And my entity have a property of type Address:
public class Person
{
...
public int Id { get; set; }
public Address Info { get; set; }
...
}
I'm encountering a problem when updating my entity's address information using my UpdateInfo method and DbContext.Update.
When calling the method below, the updated data is not saved into the database:
public void UpdatePerson(int id)
{
Person person = _dbContext.Persons.Find(id);
person.Info.UpdateInfo("First Avenue", "New York City", "10001");
_dbContext.Persons.Update(person);
_dbContext.SaveChanges();
}
After some investigation I noticed that DbContext.Update makes a shallow copy of my Person instance, and if I instead do something like the code below, the data in the database will be updated correctly:
public void UpdatePerson_ForceDeepCopy(int id)
{
Person person = _dbContext.Persons.Find(id);
person.Info = new Address()
{
Street = "'First Avenue",
City = "New York City",
Zipcode = "10001"
};
_dbContext.Persons.Update(person);
_dbContext.SaveChanges();
}
I don't like this solution so much, I would much rather updating the existing instance of Address over creating a new one.
Does anyone know if it's possible, and if so, how can I configure my DbContext to perform a deep copy of my Owned instances when I use DbContext.Update?
Thanks.
You could modify your first method to explicitly set the Info property as modified:
But anyway I would use the second method you showed, if we are really talking about the address of a person. If the db context is set to track entities, then this line is not needed:
_dbContext.Persons.Update(person);if you really need not to instantiate an "Address" (maybe this is just an example) then my first suggestion should work.