为实现接口的所有类型(具有

时间:2016-09-08 07:52:14

标签: entity-framework ef-fluent-api ef-model-builder

我有许多继承自Interface' IEventReportElement'的类型,它公开了属性' IdEventReport':

public interface IEventReportElement
{
    long Id { get; set; }
    long? IdEventReport { get; set; }
}

这是一个可以为空的属性,因为我并不总是能够立即正确填写它,但在数据库中应该不可为空。

这就是为什么我添加了行

modelBuilder.Types<IEventReportElement>().Configure(x=>x.Property(y=>y.IdEventReport).IsRequired());

到DbContext中的OnModelCreating方法。

但是,Type&#39; Position&#39;必须实现此接口,但不应该具有属性&#39; IdEventReport&#39;在数据库中,而是属性&lt; Idaparent&#39;它暴露了。

public class Position : BOBase, IEventReportElement
{
    public long? IdEventReport 
    {
        get { return IdParent; }
        set { IdParent = value; }
    }

    public long? IdParent { get; set; }
}

和modelBuilder中的部分

        modelBuilder.Entity<Position>().Property(x => x.IdParent).IsRequired();
        modelBuilder.Entity<Position>().Ignore(x => x.IdEventReport);

但是,在尝试创建数据库时,这会引发异常:

  

System.InvalidOperationException:属性&#39; IdEventReport&#39;不是类型&#39;位置&#39;的声明属性。使用Ignore方法或NotMappedAttribute数据批注验证是否未从模型中显式排除该属性。确保它是有效的原始属性。

虽然这可能有效,但是不能覆盖特定类型的给定Type配置吗?我是否必须将.IsRequired()行添加到实现此接口的每个其他类型,还是有其他方法可以解决这个问题?

2 个答案:

答案 0 :(得分:0)

如果您只是希望该列在数据库中具有不同的名称,请使用HasColumnName

要在C#模型中访问IdParent,请使用[NotMapped]告诉EF在创建数据库时忽略此属性。

public class Position : BOBase, IEventReportElement {
    public long? IdEventReport {get; set; }

    [NotMapped]
    public long? IdParent {
        get { return IdEventReport ; }
        set { IdEventReport = value; }
    } 
}

modelBuilder.Entity<Position>().Property(x => x.IdEventReport).HasColumnName("IdParent");

作为旁注:你为什么要实现一个你不想使用的界面?也许你可以将界面分成较小的部分,只实现你将要使用的东西。

答案 1 :(得分:0)

我确实找到了一个解决方案,但它不是那么好。我是通过将类型配置的行修改为

来实现的
modelBuilder.Types<IEventReportElement>().Where(x=>x.Name!="Position").Configure(x=>x.Property(y=>y.IdEventReport).IsRequired());