开发者

Wrong column name in table per subclass strategy with abstract class in hierarchy

开发者 https://www.devze.com 2023-04-11 07:38 出处:网络
Consider the following class hierarchy: public abstract class Entity { public virtual int Id { get; private set; }

Consider the following class hierarchy:

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

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

public abstract class ConfiguredVariableEditableBlockEnt开发者_JAVA技巧ity
    : ConfiguredBlockEntity
{
    public virtual VariableEditableBlockEntity TemplateBlock { get; set; }
}

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

I am using the automapping feature of Fluent NHibernate.

This creates the following table structure:

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

There are some problems with this result:

  1. The table ConfiguredPhoneNumberBlockEntity has one column that is primary key and foreign key to the base class in one (column ConfiguredVariableEditableBlockId. This looks strange and doesn't conform to how I normally design my tables. If I would have designed the table by hand, it would have an Id column that is the PK and an ConfiguredBlockId columnt that is the FK. Can I change this somehow with fluent or automapping?
  2. The PK/FK column is named ConfiguredVariableEditableBlockId, but there exists no table ConfiguredVariableEditableBlock, because it was an abstract base class and its property has been incorporated into ConfiguredPhoneNumberBlockEntity table. This column references the table ConfiguredBlockEntity and thus should be named accordingly. How to fix this in fluent or automapping?


  1. an inheritance table doesnt need an extra Id column, its never read alone or by id. Normally its joined with the baseclass-table. Therefor FNH defaults to this design. You can enforce your design for example with FluentMappings with a hidden Property Id as Readonly (additional work for no 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");
        }
    }
    

Edit: or more general

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号