实体框架6.1和使用新关键字隐藏的成员

时间:2014-04-21 21:44:30

标签: c# entity-framework

我有一堆实体实现了一个名为ICreatableEntity的接口。定义是:

public interface ICreatableEntity {
    int CreatedById { get; set; }
    Employee CreatedBy { get; set; }
    DateTime CreatedDateTime { get; set; }
}

一个特定的实体Employee需要稍加修改,因为第一个记录不能有创建者,因此我需要使列可以为空。所以,我只是尝试使用new关键字隐藏继承的成员,如:

public new int? CreatedById { get; set; }

一切正常,编译器喜欢它和所有,但是当模型由EF生成时,它会因为项目已存在于元数据集合中而崩溃。我猜,EF可能首先添加我的覆盖,然后继续添加基本属性,即使我试图隐藏它,那就是它崩溃的时候。

更新:我试图保持原样并在Fluent API配置中将其更改为Optional,它也编译得很好,但是当插入我的种子数据时再次崩溃,因为我仍然留下它实际上是空的。

是否有一个解决方法,不需要我翻转逻辑并使其可以为所有内容为空,然后添加几十个Fluent API配置来告诉EF它实际上是否需要其他地方?

更新:为了提供更多信息,每次EF都会重新生成数据库,因为我没有使用任何预先存在的内容。

1 个答案:

答案 0 :(得分:0)

我找到了一个我非常满意的解决方案。我指出,在指定外键时,我可以使用Fluent API HasForeignKey()Map()HasForeignKey()要求您在实体上指定已存在的属性,但Map()允许您指定EF将为您生成的属性的名称作为外键。由于在使用任一方法之前,关系已经被配置为必需或可选(HasRequired()HasOptional()),因此可以考虑可为空性。

所以,我只是这样做,并从我的接口中删除了显式属性声明,这自动神奇地解决了我遇到的整个问题。这也有助于我开始使用基本配置类,它为实现我的接口的实体做了很多繁重的工作。我只需要为Employee配置覆盖一次特定方法,就可以了。

这是一个缩短版本的基本配置类,使事情发生。

internal class Configuration<TEntity> :
    EntityTypeConfiguration<TEntity>
    where TEntity : class, ICreatableEntity, new() {
    protected virtual void Configure() {
        this.Configure(ConfigurationParameters.Default);
    }

    protected virtual void Configure(
        ConfigurationParameters parameters) {
        this.ConfigureCreatableRelationships(parameters.CreatedByWillCascadeOnDelete);
    }

    #region Relationship Configurations
    protected virtual void ConfigureCreatableRelationships(
        bool willCascadeOnDelete) {
        this.HasRequired(
            t =>
                t.CreatedBy).WithMany().Map(
            m =>
                m.MapKey("CreatedById")).WillCascadeOnDelete(willCascadeOnDelete);
    }
    #endregion
}

我的EmployeeConfiguration课程中的覆盖:

internal sealed class EmployeeConfiguration :
    Configuration<Employee> {
    protected override void ConfigureCreatableRelationships(
        bool willCascadeOnDelete) {
        this.HasOptional(
            t =>
                t.CreatedBy).WithMany().Map(
            m =>
                m.MapKey("CreatedById"));
    }
}

我希望将来可以帮助某人。