我应该为我的基类使用实体框架上的啥继承策略?

Posted

技术标签:

【中文标题】我应该为我的基类使用实体框架上的啥继承策略?【英文标题】:What inheritance strategy on Entity Framework should I use for my base class?我应该为我的基类使用实体框架上的什么继承策略? 【发布时间】:2018-03-18 19:19:00 【问题描述】:

我有一个带有属性的基类:

Id, CreatedOn, LastModifiedOn, DeletedOn, IsDeleted

我所有的具体类都继承自这个基类。我应该为基类创建一个单独的表,还是应该在每个具体类的表中包含那些继承的属性?

我对数据库规范化不是很熟悉,我在想在这种情况下是否可以重复列。

【问题讨论】:

在不知道派生类和其他要求的情况下无法回答。无法根据这一点信息来选择继承策略——甚至决定是否全部继承。开始阅读here 并做出选择。 【参考方案1】:

如果您正在执行schema-first,您的代码将(或应该)自动生成,因此这些公共属性没有任何好处,除非您在其中执行一些业务逻辑(可以'不知道为什么)。让生成的类与表匹配。即每个人都有IDCreatedOn; LastModified 等。当代码自动生成时,让它生成所有内容通常是有意义的。

手工制作的代码优先可能是另一回事,因为您完全可以在考虑到这些属性的情况下使用基类。对这些特定属性执行此操作几乎没有什么好处,只会导致可能混淆某个类中的哪些属性存在于相应的表中。

我应该为基类创建一个单独的表,还是应该只在每个具体类的表中包含那些继承的属性?

我可能会将它们放在同一个表中,因为在写操作期间,您不想修改核心表然后更新另一个只是为了修改LastModifiedOn。这样做总是需要事务,这可能会导致不必要的性能损失

【讨论】:

感谢您的回复。这个场景怎么样。 BaseClass 在使用实体框架的代码优先方法时,我真的很困惑如何或是否需要规范化我的数据库。 如果我将 person 表与患者和医生分开,我可能会对基类列产生混淆。或者我的方法可能有问题。 @LanceBendo 这听起来像是一个关于如何而不是我应该的新问题。考虑在另一个特定于数据库设计的 StackExchange 站点上提问。在这里问可以说是太宽泛了。你必须问自己,“我真的需要数据库标准化吗?”。它使事情复杂化,您的应用程序可能不需要它。祝你好运。【参考方案2】:

Entity Framework 会自动为您“包含”这些属性。这意味着如果您使用 Code First,EF 将生成具有这些属性的 Db 表。

例如:

public class EntityBase
    
        [Key, Column(Order = 0)]
        public int Id  set; get;  = -1;

        private DateTime? createDate;

        public DateTime CreateDate
        
            set
            
                createDate = value;
            
            get
            
                if (createDate.HasValue)
                    return createDate.Value;
                else
                    return DateTime.Now;
            
        

        public DateTime? UpdateDate  set; get; 
        public DateTime? DeleteDate  set; get; 

        public bool IsDeleted  set; get; 


        public int CreatedBy  set; get; 

        public int? UpdatedBy  set; get; 

        public int? DeletedBy  set; get; 

    

假设你有:

public class Test1 : EntityBase 

     [MaxLength(500)]
     public string Name get; set;

生成的迁移将如下所示:

   CreateTable(
            "dbo.Test1",
            c => new
                
                    Id = c.Int(nullable: false, identity: true),
                    Name = c.String(maxLength: 500),
                    CreateDate = c.DateTime(nullable: false),
                    UpdateDate = c.DateTime(),
                    DeleteDate = c.DateTime(),
                    IsDeleted = c.Boolean(nullable: false),
                    CreatedBy = c.Int(nullable: false),
                    UpdatedBy = c.Int(),
                    DeletedBy = c.Int(),
                )
            .PrimaryKey(t => t.Id);

所以答案是,您不必为基类创建单独的表。

【讨论】:

你没有回答问题

以上是关于我应该为我的基类使用实体框架上的啥继承策略?的主要内容,如果未能解决你的问题,请参考以下文章

是否建议让所有类都从 C++ 中的基类继承?

从不可修改的基类继承派生成员的设计模式?

如何从 CPP 中的基类继承构造函数?

继承中的基类是不是复制到派生类?

您可以拥有与您继承的基类相同的类的私有成员吗?

C++中的指针数组