Entity framework EF6-TPT-具有可审核列的继承

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

TL;DR

我需要在现有数据库上实现TPT。我有表格:实体、公司和个人。公司和个人通过其主键(一对一)-EntityId与实体链接

相关表格包含审核列: CreateDate(非空)、ChangeDate、CreateUserId(非空)、ChangeUserId、CreateTransactionId、ChangeTransactionId,我无法删除它们。我能够正确地实现TPT和GET works,但当我尝试使用EF6将记录插入表时,它抛出了一个错误,例如,列的其中一个中的CreateDate不能为null。原因是:审核数据被映射到实体表,而它不会将该信息添加到个人/公司表中

TPT的实现方式是Person和Company类派生自实体

在使用TPT时,如何强制EF6将属性保存在两个表中?实体拆分不起作用,它会引发一个错误,即非键属性不能映射两次

如果不是EF6,那么是否有一种方法(例如预/后触发器)可以用数据填充有问题的列

背景-当前实施-使用EF6

数据库

    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; }
    }