-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update of owned entity fails #9803
Comments
This is a subcase of #7340 |
Impact: This is a common scenario for owned entities and the way to fix it is not obvious |
EF Triage: we recognize that this is an important scenario, but unfortunately there is too much risk of regressions to try to fix in a patch release. Therefore, we plan to address it in 2.1 via #7340. The workarounds for now are
public void Move(Address address)
{
if (address == null)
{
throw new ArgumentNullException(nameof(address));
}
Address.UpdateFrom(address);
}
And on Address:
```C#
internal void UpdateFrom(Address other)
{
Street = other.Street;
}
context.Entry(person.Address).State = EntityState.Detached;
person.Move(new Address("OtherStreet"));
context.Entry(person.Address).State = EntityState.Modified; |
This patch bug is approved for the 2.0.x patch. Please send a PR to the |
Could somebody clarify what exactly will be fixed in the 2.0.x patch? Will it be a real fix or just "throwing better exception when replacing an owned entity"? |
@andriysavin The patch will only include a better exception message. We recognize that there is a significant gap in functionality here, but unfortunately it can't be fixed in a patch release. We're working on it for 2.1. |
ok, at least I know I'm not going crazy ... I'll just simplify my demo for now. |
Just to note: while workaround @ajcvickers suggested may work, it breaks Value Object immutability, which is the key trait of this pattern in DDD. Some assumptions made by consuming code may break after such change. |
@andriysavin absolutely. I tried the second one - manual detach . Did not go turn the value object into a franken-thingy :) |
@julielerman I don't even consider detaching approach since it requires mixing domain/business logic with repository implementation details. Though in many cases this may be less evil than making value object mutable and allowing to spread dependency on this. |
separation of concerns for the win. I'm doing it in a service. EIther way, it didn't work. |
Hi, we have a public test feed that you can use to try out the ASP.NET/EF Core 2.0.3 patch! To try out the pre-release patch, please refer to the following guide:
We are looking for feedback on this patch. We'd like to know if you have any issues with this patch by updating your apps and libraries to the latest packages and seeing if it fixes the issues you've had, or if it introduces any new issues. If you have any issues or questions, please reply on this issue to let us know as soon as possible. Thanks, |
Hi @Eilon , this feature seems to be working ok in EF Core 2.1 RC1 with 1 level of owned types nesting. However, if you have 2 nested owned types, EF discards changes on the entity property. Its better to provide an example: using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace TestEfCtorInjectionWithOwnedTypes
{
public class MyEntity
{
public int Id { get; set; }
public OwnedEntity Owned { get; set; }
private MyEntity() { }
public MyEntity(OwnedEntity owned) => Owned = owned;
}
public class OwnedEntity
{
public OwnedOwnedEntity OwnedOwnedProperty { get; private set; }
private OwnedEntity() { }
public OwnedEntity(OwnedOwnedEntity ownedOwnedProperty)
=> OwnedOwnedProperty = ownedOwnedProperty;
}
public class OwnedOwnedEntity
{
public double MyProperty { get; private set; }
private OwnedOwnedEntity() { }
public OwnedOwnedEntity(double myProperty) => MyProperty = myProperty;
}
class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions options) : base(options) { }
public DbSet<MyEntity> MyEntities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>(cb =>
{
cb.OwnsOne(seg => seg.Owned, b =>
{
b.OwnsOne(e => e.OwnedOwnedProperty);
});
});
}
}
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddDbContext<MyDbContext>(options =>
options.UseInMemoryDatabase("MyDatabase"));
using (var sp = services.BuildServiceProvider())
{
int entityId;
using (var scope = sp.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var entity = new MyEntity(new OwnedEntity(new OwnedOwnedEntity(4242)));
dbContext.MyEntities.Add(entity);
dbContext.SaveChanges();
entityId = entity.Id;
}
using (var scope = sp.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var entity = dbContext.MyEntities.Find(entityId);
System.Console.WriteLine("MyProperty before changing: " +
entity.Owned.OwnedOwnedProperty.MyProperty);
entity.Owned = new OwnedEntity(new OwnedOwnedEntity(4848));
System.Console.WriteLine("MyProperty before saving changes: " +
entity.Owned.OwnedOwnedProperty.MyProperty);
dbContext.SaveChanges();
System.Console.WriteLine("MyProperty after saving changes: " +
entity.Owned.OwnedOwnedProperty.MyProperty);
}
}
}
}
}
The output I'm getting:
|
Hi @andriysavin , |
@ahmedtolba1984 nope, all hope to MS guys :) |
If it's any use, I wrote an article with help from @AndriySvyryd (on the EF team) about a workaround . It's here: https://msdn.microsoft.com/magazine/mt846463. Note that the workaround doesn't work with InMemory, however. :( |
@julielerman Thanks, the article is great! However, you're covering EF Core 2.0, where owned types replacement wasn't claimed to work. And I'm taking about v2.1, which as I understood should have fixed it. And looks like it has, but only partially. Replacement works without any workarounds, but only if there is no nesting of owned types. |
@AndriySvyryd thoughts? |
@andriysavin thanks for reaching out. Could you please create a new self-contained issue about values in nested owned types not being taken into account after replacement? |
@divega Yes, I will. |
Here it is #12118 |
@andriysavin thanks! |
@divega Is this fixed already? i see the label |
@HassanHashemi Yes, this issue was fixed in the 2.0.3 patch release--that's what the combination of a closed issue in a milestone means. However, there is a related issue #12118 that is still open. |
I've had this issue and written a post on how we resolved it. I hope this helps someone else. |
Is the issue fixed? Why I still have the same problem using EF Core 2.2.6? Would you please point me some guide line on how to fix it? |
@stg609 If you are still hitting a problem, then please open a new issue and include a small, runnable project/solution or complete code listing that reproduces the behavior you are seeing. |
If I update an owned entity a call to SaveChanges crashes with the exception below.
If this is not the correct way to map DDD Entities and Value Objects, then how should I do it?
The text was updated successfully, but these errors were encountered: