如何使用流利的NHibernate映射没有主键的相关表

本文关键字:映射 何使用 NHibernate | 更新日期: 2023-09-27 18:36:19

对我来说看起来很常见:我有两个表:文件:dID (pk, int), dName(varchar)

和document_options:dID (int), oType(int), oValue(varchar)

我想要一个带有属性选项的文档类(文档选项类列表)

由于document_options没有PK,我不能使用HasMany,而且这个表中的行看起来无论如何都不像"真实"实体......

我看到了一种方法可以为文档选项生成自动编号键并使用 HasMany 进行映射,或者可能创建一个复合 ID,但我想知道是否有我不知道的更好选项。

如何使用流利的NHibernate映射没有主键的相关表

在这种情况下,DocumentOptions是一个值对象,因为它没有自己的身份,并且在它所属的文档之外没有任何意义。因此,您将使用 Component 将集合属性映射到值对象。

public class Document : Entity // don't worry about Entity; it's a base type I created that contains the Id property
{
    public virtual string Name { get; set; }
    public virtual IList<DocumentOptions> Options { get; protected set; }
    public Document()
    {
        Options = new List<DocumentOptions>();
    }
}
public class DocumentOptions
{
    public virtual int Type { get; set; }
    public virtual string Value { get; set; }
}

和映射:

public DocumentMap()
{
    Table("documents");
    Id(c => c.Id)
        .Column("dId")
        .GeneratedBy.HiLo("10");
    Map(c => c.Name)
        .Column("dName");
    HasMany(c => c.Options)
        .Component(c =>
                       {
                           c.Map(c2 => c2.Value).Column("oValue");
                           c.Map(c2 => c2.Type).Column("oType");
                       })
        .Table("document_options")
        .KeyColumn("dId")
        .Cascade.AllDeleteOrphan();
}

如果我理解正确,我必须将选项映射为组件列表:

HasMany(x => x.DocumentOptions)
    .Table("document_options")
    .KeyColumn("dID")
    .Component(c => {
            c.Map(x => x.Option, "oID");
            c.Map(x => x.Value, "oValue");
    })
    .Fetch.Subselect(); //This type of join isn't strictly needed, is used for SQL optimization

类仅供参考:

public class Options {
    public virtual int Option { get; set; }
    public virtual int Value { get; set; }
}
public class Document {
    public virtual int ID { get; set; }
    public virtual String Name { get; set; }
    public virtual IList<DocumentOption> DocumentOptions { get; set; }
}