实体框架:如何包含受保护的集合<>?

时间:2016-03-03 19:03:31

标签: entity-framework entity-framework-6

我有一组地址,可以包含一个客户的多个地址(交货,发票等)

现在,我尝试在我的Customer类上使用.Include(s => s.Addresses)。地址和衍生的DeliveryAddress定义如下:

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);
}

由于它是受保护的财产,我在Mapping but not exposing ICollections in Entity Framework

找到了解决方法

我也发现了以下帖子,但这是关于映射而不是包括: How to map a protected property in EF 4.3 code first

在这里,他们将以下内容添加到包含受保护属性public static Expression<Func<Parent, ICollection<Child>>> ChildrenAccessor = f => f.ChildrenStorage;的类中。

所以我已经将这样的内容添加到我的Customer类中,如下所示: public static Expression<Func<Customer, ICollection<Address>>> AddressesAccessor = f => f.Addresses;

然后我可以使用包含Include(Customer.AddressesAccessor)的内容 这适用于映射,但我没有使用Include方法。它不断告诉我以下内容:

  

System.InvalidOperationException:指定的包含路径无效。 EntityType&#39; Web.DataAccess.Customer&#39;不会声明名称为“地址”的导航属性。

当我将地址属性的签名从protected更改回public时,一切正常。

有没有人知道如何使这个工作受保护的集合?

1 个答案:

答案 0 :(得分:0)

我测试了这个,它对我很有用。可以在https://github.com/codethug/EF.Experiments/blob/master/EF.Test/SubCollectionTests.cs找到示例项目,并通过测试。

您使用的是Fluent Mapping语法,如下所示:

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

或者您使用的是数据注释吗?

我发现当我使用数据注释而不是Fluent Mapping时,我会得到您发现的异常。但是使用Fluent Mapping可以使一切顺利运行。

我猜测当您使用数据注释时发生了什么,有很多惯例用于确定应该被视为导航属性的内容,并且由于Addresses属性受到保护,惯例说它不应该是导航属性。但是,如果您使用Fluent Mapping,则明确告知EF Addresses应该是Navigation属性。

如果你真的想使用数据注释,你可以编写一些自定义约定,但我不太熟悉如何做到这一点。

相关问题