Entity framework EF6-TPT-具有可审核列的继承
TL;DR 我需要在现有数据库上实现TPT。我有表格:实体、公司和个人。公司和个人通过其主键(一对一)-EntityId与实体链接 相关表格包含审核列: CreateDate(非空)、ChangeDate、CreateUserId(非空)、ChangeUserId、CreateTransactionId、ChangeTransactionId,我无法删除它们。我能够正确地实现TPT和GET works,但当我尝试使用EF6将记录插入表时,它抛出了一个错误,例如,列的其中一个中的CreateDate不能为null。原因是:审核数据被映射到实体表,而它不会将该信息添加到个人/公司表中 TPT的实现方式是Person和Company类派生自实体 在使用TPT时,如何强制EF6将属性保存在两个表中?实体拆分不起作用,它会引发一个错误,即非键属性不能映射两次 如果不是EF6,那么是否有一种方法(例如预/后触发器)可以用数据填充有问题的列 背景-当前实施-使用EF6 数据库Entity framework EF6-TPT-具有可审核列的继承,entity-framework,inheritance,audit,ef-database-first,table-per-type,Entity Framework,Inheritance,Audit,Ef Database First,Table Per Type,TL;DR 我需要在现有数据库上实现TPT。我有表格:实体、公司和个人。公司和个人通过其主键(一对一)-EntityId与实体链接 相关表格包含审核列: CreateDate(非空)、ChangeDate、CreateUserId(非空)、ChangeUserId、CreateTransactionId、ChangeTransactionId,我无法删除它们。我能够正确地实现TPT和GET works,但当我尝试使用EF6将记录插入表时,它抛出了一个错误,例如,列的其中一个中的CreateDat
public class ApplicationEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public int CustomerId { get; set; }
public virtual CustomerEntity Customer { get; set; }
}
public class Entity : AbstractAuditableEntity
{
public override int Id { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public int? Status { get; set; }
public string Notes { get; set; }
}
public class CustomerEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public int? Title { get; set; }
public string Surname { get; set; }
public string MiddleName { get; set; }
public string Forename { get; set; }
public virtual Entity Entity { get; set; }
}
public class CompanyEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public string CompanyName { get; set; }
public Int16 HostCompany { get; set; }
public virtual Entity Entity { get; set; }
}
我有一个看起来像这样的现有数据库:
如你所见:
- 实体是存储个人和公司所有公共信息的表
- 个人和公司扩展特定实体的数据
- 实体人和实体公司之间适用一对一关系(橙色标记)
- 应用程序通过CustomerEntityId与实体表(一对多)(橙色标记)链接
- 所有表都包含审核列(黄色标记):CreateDate(非空)、ChangeDate、CreateUserId(非空)、ChangeUserId、CreateTransactionId、ChangeTransactionId。应用程序表也包含它们,但为了简单起见,我决定不在打印屏幕上显示它们
public class ApplicationEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public int CustomerId { get; set; }
public virtual CustomerEntity Customer { get; set; }
}
public class Entity : AbstractAuditableEntity
{
public override int Id { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public int? Status { get; set; }
public string Notes { get; set; }
}
public class CustomerEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public int? Title { get; set; }
public string Surname { get; set; }
public string MiddleName { get; set; }
public string Forename { get; set; }
public virtual Entity Entity { get; set; }
}
public class CompanyEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public string CompanyName { get; set; }
public Int16 HostCompany { get; set; }
public virtual Entity Entity { get; set; }
}
所有现有类都派生自抽象AuditableEntity,这意味着它们包含:
CreatedByUserId、CreatedDate、CreateTransactionId、ChangedByUserId、ChangedDate、ChangeTransactionId
CustomerEntity(与Person表链接)和CompanyEntity具有属性实体。
此外,ApplicationEntity包含CustomerEntity的外键,借助该外键,您可以从DB中获取包含实体本身信息的对象,例如
var application = _unitOfWork.GetRepository<ApplicationEntity>().GetById(1);
var entityType = application.Customer.Entity.Type;
我尝试拆分要映射到两个表的属性,但EF表示无法执行此操作:
“公司”类型的属性只能映射一次。非键属性“CreatedDate”已映射多次。确保Properties方法只指定每个非键属性一次
最后
我想要的是:
- 表的审核列必须保留
- 创建新公司时,我需要为每个表填充数据。由于我不能删除审计表,我必须用相同的信息填充它们,例如,实体表将包含与公司表相同的CreateDate。 我已经考虑过在company表上添加某种预插入触发器,但它似乎不适用于EF查询
public class ApplicationEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public int CustomerId { get; set; }
public virtual BaseEnterpriseEntity Customer { get; set; } // or Entity as type
}
public class Entity : AbstractAuditableEntity
{
public override int Id { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public int? Status { get; set; }
public string Notes { get; set; }
}
public abstract class BaseEnterpriseEntity : Entity
{
public override int Id { get; set; }
}
public class CustomerEntity : BaseEnterpriseEntity
{
public override int Id { get; set; }
public int? Title { get; set; }
public string Surname { get; set; }
public string MiddleName { get; set; }
public string Forename { get; set; }
}
public class CompanyEntity : BaseEnterpriseEntity
{
public override int Id { get; set; }
public string CompanyName { get; set; }
public Int16 HostCompany { get; set; }
}
public class ApplicationEntity : AbstractAuditableEntity
{
public override int Id { get; set; }
public int CustomerId { get; set; }
public virtual BaseEnterpriseEntity Customer { get; set; } // or Entity as type
}
public class Entity : AbstractAuditableEntity
{
public override int Id { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public int? Status { get; set; }
public string Notes { get; set; }
}
public abstract class BaseEnterpriseEntity : Entity
{
public override int Id { get; set; }
}
public class CustomerEntity : BaseEnterpriseEntity
{
public override int Id { get; set; }
public int? Title { get; set; }
public string Surname { get; set; }
public string MiddleName { get; set; }
public string Forename { get; set; }
}
public class CompanyEntity : BaseEnterpriseEntity
{
public override int Id { get; set; }
public string CompanyName { get; set; }
public Int16 HostCompany { get; set; }
}