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