【问题标题】:Entity Framework: how to include protected Collection<>?实体框架:如何包含受保护的 Collection<>?
【发布时间】:2016-03-05 02:45:08
【问题描述】:

我有一个地址集合,其中可以包含一个客户的多个地址(交货、发票等)

现在,我尝试在我的 Customer 类中使用 .Include(s =&gt; 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&lt;Func&lt;Parent, ICollection&lt;Child&gt;&gt;&gt; ChildrenAccessor = f =&gt; f.ChildrenStorage; 的类中。

所以我在我的 Customer 类中添加了相同的内容,如下所示: public static Expression&lt;Func&lt;Customer, ICollection&lt;Address&gt;&gt;&gt; AddressesAccessor = f =&gt; f.Addresses;

然后我可以使用包含 Include(Customer.AddressesAccessor) 这对映射很有用,但我没有让它与 Include 方法一起使用。它不断告诉我以下内容:

System.InvalidOperationException:指定的包含路径无效。 EntityType 'Web.DataAccess.Customer' 未声明名为 'Addresses' 的导航属性。

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

有谁知道如何使这项工作适用于受保护的收藏?

【问题讨论】:

  • 看起来你需要它是public。那么为什么要将其设置为protected?将其保留为 public 有什么问题,因为您希望其他类能够访问该属性?
  • 收藏品已经存在于客户身上。我想添加一些额外的 publicproperties 按类型公开地址,而不是一直对集合进行 linq 查询。有了这些额外的public 属性,集合就不再需要public

标签: entity-framework entity-framework-6


【解决方案1】:

我对此进行了测试,对我来说效果很好。可以在 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();
    }

或者您正在使用数据注释?

我发现当我使用 Data Annotations 而不是 Fluent Mapping 时,我会得到你发现的异常。但是使用 Fluent Mapping 可以让一切顺利进行。

我猜发生的事情是当您使用数据注释时,有很多约定被用来确定什么应该被视为导航属性,并且由于 Addresses 属性受到保护,约定说它应该'不是导航属性。但是,如果您使用 Fluent Mapping,您会明确告诉 EF Addresses 应该是 Navigation 属性。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多