Efcore: Problem seeding data that contains owned type

Created on 15 May 2018  路  5Comments  路  Source: dotnet/efcore

Hello...
If seed the database with the sample data bellow using HasData I'll get the following error:

The seed entity for entity type 'Location' with the key value 'Id:1' cannot be added because it has the navigation 'Position' set. To seed relationships you need to add the related entity seed to 'Position' and specify the foreign key values {'LocationId'}.

Sample data:

{
    "id": 1,
    "name": "Second Avenue",
    "position": {
      "x": 0,
      "y": 0,
      "z": 0
    }
  }

It seems that EF is not recognizing my position property as an owned type even though I have configured it so: modelBuilder.Entity<Location>().OwnsOne(l => l.Position);.

closed-question customer-reported

Most helpful comment

@thiagomajesk Owned types must be seeded with a HasData call after the OwnsOne call. Also, since owned types by convention have a primary key generated in shadow state, and since seed data requires keys to be defined, then this requires use of an anonymous type and setting the key. For example:
```C#
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}

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

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(b =>
{
b.HasData(new
{
Id = 1,
Name = "Spin"
});

    b.OwnsOne(e => e.Address).HasData(new
    {
        BlogId = 1,
        Street = "11 Meadow Drive",
        Zip = "DN37 7RU"
    });
});

}
```
Note that this would become easier if navigations were supported for seeding, which is tracked by #10000.

All 5 comments

@thiagomajesk Owned types must be seeded with a HasData call after the OwnsOne call. Also, since owned types by convention have a primary key generated in shadow state, and since seed data requires keys to be defined, then this requires use of an anonymous type and setting the key. For example:
```C#
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}

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

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(b =>
{
b.HasData(new
{
Id = 1,
Name = "Spin"
});

    b.OwnsOne(e => e.Address).HasData(new
    {
        BlogId = 1,
        Street = "11 Meadow Drive",
        Zip = "DN37 7RU"
    });
});

}
```
Note that this would become easier if navigations were supported for seeding, which is tracked by #10000.

@ajcvickers Thanks for the explanation, that's in line with the docs regarding how owned types work using shadow properties. However, I think we could benefit from a little bit of clarity describing this scenario on the seeding section. What do you think?

@ajcvickers Is there a way to seed without explicitly providing Id?

@Deilan Not currently. In this case, #10000 would allow that.

Was this page helpful?
0 / 5 - 0 ratings