Home > Software engineering >  How to configure Owned type referencing another entity in ef core 6
How to configure Owned type referencing another entity in ef core 6

Time:12-26

I have the following entity called Slot.

public class Slot : Entity
{
    public virtual SnackPile SnackPile { get; set; }
}

SnackPile here is a ValueObject and has no table of its own. Its owned by Slot. SnackPile looks like this.

public sealed class SnackPile : ValueObject<SnackPile>
{
    public static readonly SnackPile Empty = new SnackPile(Snack.None, 0, 0m);
    public Snack Snack { get; } // Please note this Snack, we will come to this.
    public int Quantity { get; }
    public decimal Price { get; }
    private SnackPile() { }
}

So to configure that, I have the following.

modelBuilder.Entity<Slot>().OwnsOne(slot => slot.SnackPile, slotToSnackpile =>
{
    slotToSnackpile.Property(ss => ss.Price).IsRequired();
    slotToSnackpile.Property(ss => ss.Quantity).IsRequired();
    //slotToSnackpile.Navigation(p => p.Snack).IsRequired(); // This is not working.
}).Navigation(slot => slot.SnackPile).IsRequired();

So far so good.

Now the SnackPile has as a property Snack, and this an entity. How to configure this? As you can see there, I tried to add this

slotToSnackpile.Navigation(p => p.Snack).IsRequired(); // This is not working.

It gives the following error.

Navigation 'SnackPile.Snack' was not found. Please add the navigation to the entity type before configuring it.

Tried the following two as well, but to no avail.

//slotToSnackpile.Property(ss => ss.Snack).IsRequired();

This gives the following error. The property 'SnackPile.Snack' is of type 'Snack' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

And with this one

//slotToSnackpile.Property(ss => ss.Snack.Id).IsRequired();

I get the error. The expression 'ss => ss.Snack.Id' is not a valid member access expression. The expression should represent a simple property or field access: 't => t.MyProperty'. (Parameter 'memberAccessExpression')

Stuck :( Any ideas?

CodePudding user response:

EF Core maps by default only properties (primitive or navigation like) having public getter and any setter (could be private, protected etc.).

Since all your properties (including the one in question) are get only (have no setters), you have to map them explicitly.

For primitive properties you use Property fluent API. But for navigation properties you need the relationship fluent API, e.g. Has / With pair. In your case:

slotToSnackpile.HasOne(e => e.Snack).WithMany().IsRequired();
  • Related