Entity Framework: how to include protected Collection<>?

entity-framework entity-framework-6

Question

I've got a collection of addresses which can contain multiple addresses for a Customer (delivery, invoice, etc.)

Now, I'm trying to use .Include(s => s.Addresses) on my Customer class. Addresses and the derivative DeliveryAddress are defined like this:

protected virtual ICollection<Address> Addresses
{
   get { return _addresses ?? (_addresses = new Collection<Address>()); }
   set { _addresses = value; }
}

[NotMapped]
public Address DeliveryAddress
{
   get { return GetAddress(AddressType.Delivery); }
}

private Address GetAddress(AddressType type)
{
   return Addresses.FirstOrDefault(a => a.Type == type);
}

Since it's a protected property, I've found a solution for this on Mapping but not exposing ICollections in Entity Framework

I Also found the following post, but this is about mappings instead of includes: How to map a protected property in EF 4.3 code first

Here they add the following to the class containing the protected property public static Expression<Func<Parent, ICollection<Child>>> ChildrenAccessor = f => f.ChildrenStorage;.

So I've added the same to my Customer class like so: public static Expression<Func<Customer, ICollection<Address>>> AddressesAccessor = f => f.Addresses;

And then i'm able to use the include with Include(Customer.AddressesAccessor) This works great for mappings, but I'm not getting it to work with the Include method. It keeps telling me the following:

System.InvalidOperationException: A specified Include path is not valid. The EntityType 'Web.DataAccess.Customer' does not declare a navigation property with the name 'Addresses'.

When I change the signature of the Addresses property from protected back to public all works fine.

Does anyone know how to make this work for protected collections?

1
0
5/23/2017 11:59:59 AM

Accepted Answer

I tested this out, and it worked great for me. A sample project can be found at https://github.com/codethug/EF.Experiments/blob/master/EF.Test/SubCollectionTests.cs with tests that pass.

Are you using the Fluent Mapping syntax, like this:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasMany(Customer.AddressesAccessor)
            .WithRequired();
    }

Or are you using Data Annotations?

I found that when I used Data Annotations instead of the Fluent Mapping, I would get the exception you found. But using Fluent Mapping made everything work without trouble.

I'm guessing that what's happening is when you use Data Annotations, there is a lot of convention being used to figure out what should be considered a Navigation Property, and since the Addresses property is protected, the convention says that it shouldn't be a Navigation property. However, if you use the Fluent Mapping, you are explicitly telling EF that Addresses should be a Navigation property.

If you really want to use Data Annotations, you can probably code up some custom conventions, but I'm not too familiar with how that could be done.

0
3/4/2016 6:45:08 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