c# - 每个子类策略在表中的列名错误,层次结构中有抽象类

标签 c# .net nhibernate fluent-nhibernate nhibernate-mapping

考虑以下类层次结构:

public abstract class Entity
{
    public virtual int Id { get; private set; }
}

public class ConfiguredBlockEntity : Entity
{
    public virtual ScheduledGreetingEntity ScheduledGreeting { get; set; }
}

public abstract class ConfiguredVariableEditableBlockEntity
    : ConfiguredBlockEntity
{
    public virtual VariableEditableBlockEntity TemplateBlock { get; set; }
}

public class ConfiguredPhoneNumberBlockEntity
    : ConfiguredVariableEditableBlockEntity
{
    public virtual string PhoneNumber { get; set; }
}

我正在使用 Fluent NHibernate 的自动映射功能。
这将创建以下表结构:

create table "BlockEntity" (
    Id INT IDENTITY NOT NULL,
   ExecutionOrder INT null,
   Name NVARCHAR(255) null,
   BlockType NVARCHAR(255) null,
   GreetingId INT null,
   primary key (Id)
);

create table "ConfiguredBlockEntity" (
    Id INT IDENTITY NOT NULL,
   ScheduledGreetingId INT null,
   primary key (Id)
);

create table ConfiguredPhoneNumberBlockEntity (
    ConfiguredVariableEditableBlockId INT not null,
   PhoneNumber NVARCHAR(255) null,
   VariableEditableBlockId INT null,
   primary key (ConfiguredVariableEditableBlockId)
);

alter table ConfiguredPhoneNumberBlockEntity 
    add constraint FK87F9EFC9BB9A4B52 
    foreign key (ConfiguredVariableEditableBlockId) 
    references "ConfiguredBlockEntity";

这个结果有一些问题:

  1. ConfiguredPhoneNumberBlockEntity 有一列是基类的主键和外键(列 ConfiguredVariableEditableBlockId)。这看起来很奇怪,不符合如何我通常设计我的表格。如果我手动设计表格,它会有一个作为 PK 的 Id 列和一个作为 FK 的 ConfiguredBlockId 列。< strong>我可以用流利或自动映射以某种方式改变它吗?
  2. PK/FK 列名为 ConfiguredVariableEditableBlockId,但不存在表 ConfiguredVariableEditableBlock,因为它是一个抽象基类,其属性已合并到 ConfiguredPhoneNumberBlockEntity 表。此列引用表 ConfiguredBlockEntity,因此应相应地命名。 如何在流利或自动映射中解决此问题?

最佳答案

  1. 继承表不需要额外的 Id 列,它永远不会单独读取或按 id 读取。通常它与基类表连接。因此 FNH 默认采用这种设计。例如,您可以使用 FluentMappings 强制执行您的设计,将隐藏的 Property Id 设置为只读(额外的工作没有值(value))。

  2. class MyJoinedSubclassConvention : IJoinedSubclassConvention,
                                       IJoinedSubclassConventionAcceptance
    {
        public void Accept(IAcceptanceCriteria<IJoinedSubclassInspector> criteria)
        {
            criteria.Expect(x => x.Name == "ConfiguredPhoneNumberBlockEntity");
        }
    
        public void Apply(IJoinedSubclassInstance instance)
        {
            instance.Key.Column("baseclassId");
        }
    }
    

编辑:或更一般

class MyJoinedSubclassConvention : IJoinedSubclassConvention
{
    public void Apply(IJoinedSubclassInstance instance)
    {
        Type basetype = instance.Extends;
        while (basetype.IsAbstract)
        {
            basetype = basetype.BaseType;
        }
        instance.Key.Column(basetype.Name + "Id");
    }
}

关于c# - 每个子类策略在表中的列名错误,层次结构中有抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7672477/

相关文章:

c# - 正则表达式匹配以逗号分隔的列表,末尾没有逗号

c# - 了解 C# WPF 中的文本范围

NHibernate:引用需要内连接而不是左连接

nhibernate - 每个线程的 NHibernate session 是否与线程池一起使用?

C# - 我无法引用 HttpPostedFileBase

c# - WPF 破坏布局

c# - .NET 未处理的异常对话框未出现

NHibernate:创建一个ConnectionProvider来动态选择要连接的几个数据库中的哪个?

c# - .NET 工具提示控件,可以显示在屏幕上的任何位置

c# - 在 LINQ 中使用 Union 合并列表时删除重复项