繁体   English   中英

(流利的)NHibernate表每层次结构; Id只与鉴别器一起使用

[英](Fluent) NHibernate table-per-hierarchy; Id is only unique along with discriminator

我有遗留数据库映射问题。 数据库将其所有查找值(代码/描述)存储在一个表中,由类型代码字段区分。 引用它的表使用一列(代码,没有类型代码)。 代码表没有主键约束(!)。

我有一个看起来像这样的课程:

public class Code
{
    [StringLength(8)]
    public virtual string CodeValue { get; set; }
    [StringLength(2000)]
    public virtual string Description { get; set; }
    public virtual long? OrderBy { get; set; }
    public virtual DateTime? StopDate { get; set; }
}

我的初始映射看起来像这样:

public class CodesMap : ClassMap<Code>
{
    public CodesMap()
    {
        Table("CODES");
        Id(x => x.CodeValue).Column("CODE_CODE").GeneratedBy.Assigned();
        Map(x => x.Description).Column("DESCRIPTION");
        Map(x => x.OrderBy).Column("ORDER_BY");

        DiscriminateSubClassesOnColumn("TYPE_CODE", "INVALID")
            .SqlType("VARCHAR2");
    }
}

然后有一堆子类只有它们的鉴别器值不同。

另一个映射可能将此引用为:

...
        References<FacilityType>(x => x.Type).Column("FACIL_TYPE_CODE").ReadOnly();
...

现在,这一切都很好,并且一切正常,因为该引用知道了类,因此知道了查询的鉴别器值,除了......我只是遇到了CODE_CODE在两个不同的对象之间是非唯一的情况类型(代码的两个子类型)在同一个会话中。 哎呀。

CODE_CODE和TYPE_CODE是唯一的,因此正确的做法应该是将它们用作复合键。 但是后来我在其他类映射中的引用变得不可能,因为这些表只有一个列外键(显然没有在表上定义FK约束)。

没有在代码表上添加代理键,我该怎么办?

如果我们需要将查找值映射为只读,那么解决方案将非常简单。 我们将显式映射每个子类,而不是显式继承。 鉴别符将被移动到WHERE子句:

public FacilityTypeMap()
{
    Table("CODES");

    // here we will use explicit runtime discriminator
    // injected by NHibernate into each SELECT .. FROM clause for this type
    Where(" TYPE_CODE = 'FACIL_TYPE' " )        

    Id(x => x.CodeValue).Column("CODE_CODE").GeneratedBy.Assigned();
    Map(x => x.Description).Column("DESCRIPTION");
    Map(x => x.OrderBy).Column("ORDER_BY");

    // no more inheritance
    // DiscriminateSubClassesOnColumn("TYPE_CODE", "INVALID")
    //    .SqlType("VARCHAR2");
}

这非常适合SELECT。 我们只需要为每个Discriminator ==每个派生类型重复该映射。

5.1.3。 课程

<class
    name="ClassName"                              (1)
    table="tableName"                             (2) 
    ...
    where="arbitrary sql where condition"         (11)

(11) where (可选)指定在检索此类的对象时要使用的任意SQL WHERE条件

如果我们需要使用这个类进行插入,我们还需要做更多的步骤。 将列'TYPE_CODE'显式映射为例如Discriminator,并在构造函数中将其设置为更正值(例如'FACIL_TYPE' )。 它可以被保护属性映射为.Not.Update()

string _discriminator = "FACIL_TYPE";
public virtual string Discriminator { get { return _discriminator; } protected set {} }
...
// mapping
Map(x => x.Discriminator, "TYPE_CODE").Not.Update()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM