c# - Entity Framework 6.1 和使用新关键字隐藏成员

标签 c# entity-framework

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

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 配置中将其更改为可选,这也可以正常编译,但在插入我的种子数据时再次崩溃,因为我仍然将其有效保留为空。

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

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

最佳答案

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

所以,我只是这样做了,并从我的接口(interface)中删除了显式属性声明,这自动神奇地解决了我遇到的整个问题。这也有助于我开始使用一个基本配置类,它为实现我的接口(interface)的实体做了很多繁重的工作。我只需要为 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"));
    }
}

我希望这对以后的人有帮助。

关于c# - Entity Framework 6.1 和使用新关键字隐藏成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23206559/

相关文章:

performance - 调试 Entity Framework SQL 语句

ASP.NET 身份数据库第一个自定义用户和角色

c# - 将强类型列表添加到数据库

c# - 创建一个只能由当前登录用户访问的文件夹

c# - Visual Studio 跳转到快捷方式

对象属性的 C# Web 服务序列化

c# - 数据库验证错误。在一个表中允许空值,但在相关(规范化)表中不允许空值

c# - 使用 TweetSharpAPI 获取所有用户的推文

c# - .Net 的缓冲电子邮件记录器(最好是 NLog 目标)?

entity-framework - 返回 EF 模型类