EF Core OwnsOne fails when saving

ef-migrations entity-framework entity-framework-core

Question

I have the following model:

public class User
{
    public Guid Id {get;set;}
    public string Username {get;set;}
    public string Address Useraddress {get;set;}
}

public class Address
{
    public string Street {get;set;}
    public string Zipcode {get;set;}
}

I want to save the data in Useraddress to the same User table. So I added an OwnsOne configuration to the context builder.

class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.HasKey(x => x.Id);
        builder.OwnsOne(x => x.UserAddress);
    }
}

When I run the migrations tool then it all seems to be fine. This is the relevant part from the migrations script that is generated:

migrationBuilder.CreateTable(
    name: "Users",
    columns: table => new
    {
        Id = table.Column<Guid>(nullable: false),
        Username = table.Column<string>(nullable: false),
        Useraddress_Street = table.Column<string>(nullable: true),
        Useraddress_Zipcode = table.Column<string>(nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Users", x => x.Id);
    });

Then when I later on try to add a User:

await _dbContext.Users.AddAsync(user);
await _dbContext.SaveChangesAsync();

I then get the following error:

The entity of 'User' is sharing the table 'Users' with 'User.Useraddress#Address', but there is no entity of this type with the same key value that has been marked as 'Added'

Is there something that I'm doing wrong?

PS. I'm using Entity Framework Core 2.0.

1
8
3/19/2018 7:31:06 PM

Accepted Answer

EF Core 2.0 by default creates a primary key as a shadow property for the owned entity since it supports table splitting, therefore, the value of the UserAddress property in the User instance cannot be null and must be defined.

var user = new User
{
    Id = Guid.NewGuid(),
    Username = "...",
    UserAddress = new Address
    {
        Street = "...",
        Zipcode = "..."
    }
};

await _dbContext.Users.AddAsync(user);
await _dbContext.SaveChangesAsync();

If you want the values of the owned entity to be nulls then just define a default instance, i.e.:

var user = new User
{
    Id = Guid.NewGuid(),
    Username = "...",
    UserAddress = new Address()
};

You can read more about owned entity implicit keys here: https://docs.microsoft.com/en-us/ef/core/modeling/owned-entities#implicit-keys

13
3/19/2018 11:33:07 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow