【问题标题】:EF Code First prevent property mapping with Fluent APIEF Code First 防止使用 Fluent API 进行属性映射
【发布时间】:2013-02-14 08:45:59
【问题描述】:

我有一个类 Product 和一个复杂类型 AddressDetails

public class Product
{
    public Guid Id { get; set; }

    public AddressDetails AddressDetails { get; set; }
}

public class AddressDetails
{
    public string City { get; set; }
    public string Country { get; set; }
    // other properties
}

是否可以防止在 AddressDetails 内映射“国家”属性 Product 类? (因为Product 类我永远不需要它)

类似的东西

Property(p => p.AddressDetails.Country).Ignore();

【问题讨论】:

  • 您是否覆盖了DbContext.OnModelCreating?那个方法中的modelBuilder.Entity<Product>().Ignore(p => p.AddressDetails.Country) 会失败吗?
  • 是的,没错,但是 Ignore() 方法不存在。
  • 您是否考虑过为Product.AddressDetail 使用不同的类。它显然与其他地方使用的AddressDetail 有不同的行为。
  • @RaraituL 你的意思是你试图避免 SOLID 设计? en.wikipedia.org/wiki/Liskov_substitution_principle
  • @RaraituL 忽略代码,如果有效,将破坏 LSP。如果您采用一个假定 Country != null 的函数并针对 Product.AddressDetail 运行它,它将抛出。因此违反了 LSP。 PS。更少的类不等于简单。在您的情况下,您创建了一个新的边缘情况,这不是 KISS。

标签: c# entity-framework ef-code-first fluent-interface


【解决方案1】:

对于 EF5 及更早版本: 在 DbContext.OnModelCreating 覆盖您的上下文:

modelBuilder.Entity<Product>().Ignore(p => p.AddressDetails.Country);

对于 EF6: 你不走运。见Mrchief's answer。

【讨论】:

  • 不起作用:The expression 'p =&gt; p.AddressDetails.Country' is not a valid property expression. The expression should represent a property: C#: 't =&gt; t.MyProperty' VB.Net: 'Function(t) t.MyProperty'.
  • @Mrchief 对,这是针对旧版本的。我已经为您的答案添加了一个链接,因为这是当前 EF 版本的正确链接。
  • 很遗憾他们会在 EF6 中积极阻止这种情况。希望这是出于某种隐藏的充分理由。
  • 这真的很烦人。他们似乎已经删除了功能。
【解决方案2】:

不幸的是,接受的答案不起作用,至少在 EF6 中不起作用,尤其是在子类不是实体的情况下。

我还没有找到通过 fluent API 执行此操作的任何方法。它的唯一工作方式是通过数据注释:

public class AddressDetails
{
    public string City { get; set; }

    [NotMapped]
    public string Country { get; set; }
    // other properties
}

注意:如果您遇到 Country 仅当它是某个其他实体的一部分时才应排除的情况,那么您对这种方法不走运。

【讨论】:

  • if the child class is not an entity 是什么意思?如果子类是ComplexType?
  • 是的。如果是实体,可以自己添加配置,跳过映射。
  • @Mrchief 你可以试试 modelBuilder.ComplexType().Ignore(ad => ad.Country);使用 Fluent API 实现相同的结果。
【解决方案3】:

如果您使用的是 EntityTypeConfiguration 的实现,您可以使用 Ignore 方法:

public class SubscriptionMap: EntityTypeConfiguration<Subscription>
{
    // Primary Key
    HasKey(p => p.Id)

    Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    Property(p => p.SubscriptionNumber).IsOptional().HasMaxLength(20);
    ...
    ...

    Ignore(p => p.SubscriberSignature);

    ToTable("Subscriptions");
}

【讨论】:

  • 你是什么意思它不适用于复杂类型?当您在属性声明中添加 virtual 关键字时,会自动完成复杂类型的映射。如果您不想映射它,只需删除 virtual 关键字即可。
  • 哦..你的意思是在嵌套对象中...我明白了。
【解决方案4】:

虽然我意识到这是一个老问题,但答案并没有解决我的 EF 6 问题。

对于 EF 6,您需要创建一个 ComplexTypeConfiguration 映射。

示例:

public class Workload
{
    public int Id { get; set; }
    public int ContractId { get; set; }
    public WorkloadStatus Status {get; set; }
    public Configruation Configuration { get; set; }
}
public class Configuration
{
    public int Timeout { get; set; }
    public bool SaveResults { get; set; }
    public int UnmappedProperty { get; set; }
}

public class WorkloadMap : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<Workload>
{
    public WorkloadMap()
    {
         ToTable("Workload");
         HasKey(x => x.Id);
    }
}
// Here This is where we mange the Configuration
public class ConfigurationMap : ComplexTypeConfiguration<Configuration>
{
    ConfigurationMap()
    {
       Property(x => x.TimeOut).HasColumnName("TimeOut");
       Ignore(x => x.UnmappedProperty);
    }
}

如果您的 Context 手动加载配置,您需要添加新的 ComplexMap,如果您使用 FromAssembly 重载,它将与其余配置对象一起被拾取。

【讨论】:

    【解决方案5】:

    在 EF6 上您可以配置复杂类型:

     modelBuilder.Types<AddressDetails>()
         .Configure(c => c.Ignore(p => p.Country))
    

    这样属性 Country 将始终被忽略。

    【讨论】:

      【解决方案6】:

      试试这个

      modelBuilder.ComplexType<AddressDetails>().Ignore(p => p.Country);
      

      它在类似情况下对我有用。

      【讨论】:

        【解决方案7】:

        Fluent API 也可以,只需在映射中添加以下代码

        this.Ignore(t => t.Country),在 EF6 中测试

        【讨论】:

        • 问题是关于忽略复杂类型的属性。在 EF6 下无法运行的精确场景。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-26
        相关资源
        最近更新 更多