Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with IReadOnlyCollection property in EfCore 2.1

I've got the following domain entity:

public string Reference { get; private set; }
public int SupplierId { get; private set; }
public int BranchId { get; private set; }
public Guid CreatedBy { get; private set; }
public DateTime CreatedDate { get; private set; }
public Source Source { get; private set; }
public OrderStatus OrderStatus { get; private set; }
public decimal NetTotal { get; private set; }
public decimal GrossTotal { get; private set; }

private List<PurchaseOrderLineItem> _lineItems = new List<PurchaseOrderLineItem>();
public IReadOnlyCollection<PurchaseOrderLineItem> LineItems => _lineItems.AsReadOnly();

I have the following configuration for the line items:

builder.Property(x => x.LineItems)
       .HasField("_lineItems")
       .UsePropertyAccessMode(PropertyAccessMode.Field);

However, when I run my app I'm getting the following error:

The property 'PurchaseOrder.LineItems' is of type 'IReadOnlyCollection<PurchaseOrderLineItem>' which is not supported by current database provider. Either change the property CLR type or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

My understanding is that EF should only be using the backing field per my configuration?

I have tried adding the [NotMapped] attribute just to see what happened, but that didn't work.

Am I really wrong with this? Any pointers would be appreciated.

like image 382
Chris Sainty Avatar asked Jun 12 '18 09:06

Chris Sainty


1 Answers

It's possible to configure a backing field usage for a navigation property, but not via Property method which is for primitive property, and not via fluent API (doesn't exist at this time), but directly through mutable model metadata associated with the relationship:

modelBuilder.Entity<PurchaseOrder>()
    .HasMany(e => e.LineItems)
    .WithOne(e => e.PurchaseOrder) // or `WithOne() in case there is no inverse navigation property
    .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field); // <--

You can also set the mode for all entity navigation properties (you can still override it for individual properties) by using:

modelBuilder.Entity<PurchaseOrder>()
    .Metadata.SetNavigationAccessMode(PropertyAccessMode.Field);
like image 199
Ivan Stoev Avatar answered Oct 18 '22 02:10

Ivan Stoev