C# 如何使用fluent NHibernate映射没有主键的相关表

C# 如何使用fluent NHibernate映射没有主键的相关表,c#,nhibernate,fluent-nhibernate,fluent-nhibernate-mapping,C#,Nhibernate,Fluent Nhibernate,Fluent Nhibernate Mapping,在我看来,这是一种常见的情况:我有两张桌子: 文件: dID(pk,int),dName(varchar) 和文档选项: dID(int)、oType(int)、oValue(varchar) 我想要一个带有属性选项的类文档(DocumentOption类的列表) 由于document_选项没有主键,所以我不能使用HasMany,而且这个表中的行看起来也不像“真实”实体 我看到了一种为文档选项生成自动编号键的方法,并使用HasMany映射,或者创建一个复合ID,但我想知道是否有更好的选项我不知道

在我看来,这是一种常见的情况:我有两张桌子: 文件: dID(pk,int),dName(varchar)

和文档选项: dID(int)、oType(int)、oValue(varchar)

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

由于document_选项没有主键,所以我不能使用HasMany,而且这个表中的行看起来也不像“真实”实体


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

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

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

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

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; }
}
公共类选项{
公共虚拟int选项{get;set;}
公共虚拟int值{get;set;}
}
公共类文档{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟IList DocumentOptions{get;set;}
}

谢谢,经过大量阅读,我得出了一个非常相似的答案,只是它没有使用Id,可能还有其他一些琐事=)事实上,有一些类似的方法。除了忘记指定表名之外,我正在尝试使映射与您在问题中指定的表完全匹配。您介意告诉我为什么使用“受保护集”并在构造函数中创建新的选项列表吗?我的解决方案似乎可行,但您似乎比我更了解它。您不必这么做,但我这样做是为了防止API的使用者在使用集合之前忘记初始化集合时获得
NullReferenceException
。此外,我向这些消费者指出,
选项
是由API管理的,而不是由他们使用
受保护集
;他们所需要担心的只是添加、删除和/或枚举选项(如果有的话)。同样,这不是必需的,而是一个良好的实践,成为我的习惯。
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; }
}