Entity framework 首先,如何在EF6中实现继承

Entity framework 首先,如何在EF6中实现继承,entity-framework,inheritance,entity-framework-6,Entity Framework,Inheritance,Entity Framework 6,我正在尝试使用EntityFramework6.0和数据库优先的方法实现继承。我想实现继承的原因是我想在我的所有表中添加以下字段 它们是:(实际上在公共数据库设计中,我们总是添加这些审计字段) 创造的 创建时间 莫迪菲德比 ModyfiedTime 我知道,TPT(每种类型的表)是制作它的方法之一。但我不认为TPT是解决我问题的正确方法。因为TPT需要为基类型创建一个表。但就我而言,我认为这是没有必要的。有没有办法做到这一点?谢谢。我建议在这种情况下不需要数据库继承/TPT/TPH。您需要的

我正在尝试使用EntityFramework6.0和数据库优先的方法实现继承。我想实现继承的原因是我想在我的所有表中添加以下字段

它们是:(实际上在公共数据库设计中,我们总是添加这些审计字段

  • 创造的
  • 创建时间
  • 莫迪菲德比
  • ModyfiedTime

我知道,TPT(每种类型的表)是制作它的方法之一。但我不认为TPT是解决我问题的正确方法。因为TPT需要为基类型创建一个表。但就我而言,我认为这是没有必要的。有没有办法做到这一点?谢谢。

我建议在这种情况下不需要数据库继承/TPT/TPH。您需要的只是一个
IAuditable
界面:

public interface IAuditable
{
    string CreatedBy { get; set; }

    DateTimeOffset CreatedTime { get; set; }

    string ModifiedBy { get; set; }

    DateTimeOffset? ModifiedTime { get; set; }
}
那么您有两个选择:

  • 如果您确定所有实体都将是
    IAuditable
    ,则只需更改T4模板,以便所有自动生成的实体都将实现
    IAuditable

  • 如果只有部分实体可审核,则可以向这些可审核实体添加分部类,如:

    public partial class Foo
    {
        // Auto-generated properties by EF
        public int Id { get; set; }
        ...
    } 
    
    然后在另一个文件中:

    public partial class Foo : IAuditable
    {
        // No implementation because auditable fields already exists
    }
    
  • 然后,您可以从
    DbContext
    派生一个抽象类,以自动更新这些
    IAuditable
    属性:

    public abstract class AuditableDbContext : DbContext
    {
        public override int SaveChanges()
        {
            UpdateAuditableProperties();
            return base.SaveChanges();
        }
    
        public override async Task<int> SaveChangesAsync()
        {
            UpdateAuditableProperties();
            return await base.SaveChangesAsync();
        }
    
        public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
        {
            UpdateAuditableProperties();
            return await base.SaveChangesAsync(cancellationToken);
        }
    
        protected virtual void UpdateAuditableProperties()
        {
            var now = DateTimeOffset.Now;
            var userName = GetUserName();
            var changedAuditableEntities = from entry in ChangeTracker.Entries<IAuditable>()
                                           let state = entry.State
                                           where
                                               state.HasFlag(EntityState.Added) ||
                                               state.HasFlag(EntityState.Modified)
                                           select entry;
    
            foreach (var auditable in changedAuditableEntities)
            {
                var entity = auditable.Entry;
    
                switch (auditable.State)
                {
                    case EntityState.Added:
                        entity.CreatedDate = now;
                        entity.CreatedBy = userName;
                        break;
                    case EntityState.Modified:
                        entity.ModifiedDate = now;
                        entity.ModifiedBy = userName;
                        break;
                }
            }
        }
    
        protected abstract string GetUserName();
    }
    
    公共抽象类AuditableDbContext:DbContext { 公共覆盖int SaveChanges() { UpdateAuditableProperties(); 返回base.SaveChanges(); } 公共重写异步任务SaveChangesAsync() { UpdateAuditableProperties(); return wait base.SaveChangesAsync(); } 公共覆盖异步任务SaveChangesSync(CancellationToken CancellationToken) { UpdateAuditableProperties(); 返回wait base.saveChangesSync(cancellationToken); } 受保护的虚拟void UpdateAuditableProperties() { var now=DateTimeOffset.now; var userName=GetUserName(); var changedAuditableEntities=来自ChangeTracker.Entries()中的条目 让state=entry.state 哪里 state.HasFlag(EntityState.Add)|| state.HasFlag(EntityState.Modified) 选择条目; foreach(可在changedAuditableEntities中审核的var) { var实体=可审计的条目; 开关(可审核的.State) { 案例实体状态。添加: entity.CreatedDate=now; entity.CreatedBy=用户名; 打破 案例实体状态。已修改: entity.ModifiedDate=now; entity.ModifiedBy=用户名; 打破 } } } 受保护的抽象字符串GetUserName(); }
    您的
    DbContext
    可以从
    AuditableDbContext
    派生,然后实现
    GetUserName()
    ,以提供创建/修改实体的用户名。

    我建议在这种情况下不需要数据库继承/TPT/TPH。您需要的只是一个
    IAuditable
    界面:

    public interface IAuditable
    {
        string CreatedBy { get; set; }
    
        DateTimeOffset CreatedTime { get; set; }
    
        string ModifiedBy { get; set; }
    
        DateTimeOffset? ModifiedTime { get; set; }
    }
    
    那么您有两个选择:

  • 如果您确定所有实体都将是
    IAuditable
    ,则只需更改T4模板,以便所有自动生成的实体都将实现
    IAuditable

  • 如果只有部分实体可审核,则可以向这些可审核实体添加分部类,如:

    public partial class Foo
    {
        // Auto-generated properties by EF
        public int Id { get; set; }
        ...
    } 
    
    然后在另一个文件中:

    public partial class Foo : IAuditable
    {
        // No implementation because auditable fields already exists
    }
    
  • 然后,您可以从
    DbContext
    派生一个抽象类,以自动更新这些
    IAuditable
    属性:

    public abstract class AuditableDbContext : DbContext
    {
        public override int SaveChanges()
        {
            UpdateAuditableProperties();
            return base.SaveChanges();
        }
    
        public override async Task<int> SaveChangesAsync()
        {
            UpdateAuditableProperties();
            return await base.SaveChangesAsync();
        }
    
        public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
        {
            UpdateAuditableProperties();
            return await base.SaveChangesAsync(cancellationToken);
        }
    
        protected virtual void UpdateAuditableProperties()
        {
            var now = DateTimeOffset.Now;
            var userName = GetUserName();
            var changedAuditableEntities = from entry in ChangeTracker.Entries<IAuditable>()
                                           let state = entry.State
                                           where
                                               state.HasFlag(EntityState.Added) ||
                                               state.HasFlag(EntityState.Modified)
                                           select entry;
    
            foreach (var auditable in changedAuditableEntities)
            {
                var entity = auditable.Entry;
    
                switch (auditable.State)
                {
                    case EntityState.Added:
                        entity.CreatedDate = now;
                        entity.CreatedBy = userName;
                        break;
                    case EntityState.Modified:
                        entity.ModifiedDate = now;
                        entity.ModifiedBy = userName;
                        break;
                }
            }
        }
    
        protected abstract string GetUserName();
    }
    
    公共抽象类AuditableDbContext:DbContext { 公共覆盖int SaveChanges() { UpdateAuditableProperties(); 返回base.SaveChanges(); } 公共重写异步任务SaveChangesAsync() { UpdateAuditableProperties(); return wait base.SaveChangesAsync(); } 公共覆盖异步任务SaveChangesSync(CancellationToken CancellationToken) { UpdateAuditableProperties(); 返回wait base.saveChangesSync(cancellationToken); } 受保护的虚拟void UpdateAuditableProperties() { var now=DateTimeOffset.now; var userName=GetUserName(); var changedAuditableEntities=来自ChangeTracker.Entries()中的条目 让state=entry.state 哪里 state.HasFlag(EntityState.Add)|| state.HasFlag(EntityState.Modified) 选择条目; foreach(可在changedAuditableEntities中审核的var) { var实体=可审计的条目; 开关(可审核的.State) { 案例实体状态。添加: entity.CreatedDate=now; entity.CreatedBy=用户名; 打破 案例实体状态。已修改: entity.ModifiedDate=now; entity.ModifiedBy=用户名; 打破 } } } 受保护的抽象字符串GetUserName(); }
    您的
    DbContext
    可以从
    AuditableDbContext
    派生,然后实现
    GetUserName()
    来提供创建/修改实体的用户名。

    请告诉我为什么否决我的问题。谢谢。请告诉我为什么否决我的问题。谢谢。:)是的。正确的。我只是在谷歌搜索类似的东西。(EF+a