【问题标题】:NHibernate one to many with discriminatorNHibernate 一对多与鉴别器
【发布时间】:2026-02-10 04:25:01
【问题描述】:

我在映射我认为相当简单的关联时遇到了问题。

这是我尝试映射的域模型的示例:

public class MyClass
{
    IDictionary<string, DateTime> Dates { get; set; }
}


public class MyOtherClass
{
    IDictionary<string, DateTime> Dates { get; set; }
}

我希望将 Dates 属性映射到一个表中,如下所示:

TABLE Dates
COLUMNS
    ParentId    (Parent class key value)
    ParentType  (Parent class type)
    DateType    (Index value for dictionary)
    DateValue
SAMPLE
ParentId        ParentType  DateType    DateValue
----------------------------------------------------------
1               MyClass             TYPEA       2009-10-09
1               MyOtherClass        TYPEA       2009-11-08

我愿意接受有关如何更好地对此建模的建议,但基本上我想要一个一对多的关联,而不是为每个集合使用单独的表来乱扔数据库。

我在这个特定的示例中使用 DateTime,因为这就是我现在正在尝试做的事情,但它可以很容易地是任何类型,甚至是我想以相同方式建模的另一个自定义类。

知道应该如何映射吗?

我相信这与我之前提出的问题 (NHibernate: How do I map mutiple parents' children of a common type into a single table?) 类似,但该解决方案最终出现在整个地方的交叉表中,这并不是我真正想要达到的结果。

【问题讨论】:

  • 继承模型出了什么问题?将 MyClassBase 的超类与 IDictionary Dates {get;set;} 在另一个问题中提到?这将允许您重用同一个表并使用鉴别器列
  • 我在继承模型中看到的问题是我不一定有一个公共基类。我能想到的最好的情况是创建一个带有 IDictionary Dates 属性的接口,但是我不得不实现和映射多个接口,因为我的真实模型有多个不同的集合像这样的类型需要映射。它似乎很快变得非常复杂。

标签: c# nhibernate


【解决方案1】:

区分必须在MyClassMyOtherClass 之间,而不是在日期表中。你需要这样的数据库结构:

Table Classes (for MyClass/MyOtherClass):
    ClassID (unique primary key)
    ClassType
    ...

Table Dates:
    ClassID (foreign key from above)
    Date (value)

现在,您需要一个抽象基类 MyBaseClassMyClassMyOtherClass 从中派生,然后您的映射将是这样的(伪代码,不要指望它完全正确):

<class="MyBaseClass", abstract="true" table="Classes">
  <id .../>
  <set name="Dates"... />
  <discriminator column="ClassType"/>
  <subclass type="MyNamespace.MyClass, MyAssembly" discriminator-value="'MyClass'">
    ...
  </subclass>
  <subclass type="MyNamespace.MyOtherClass, MyAssembly" discriminator-value="'MyOtherClass'">
    ...
  </subclass>
</class>

HTH!

【讨论】:

  • 这仍然依赖于一个我没有的公共基类,它也不适合创建一个。
  • 没有别的办法,如果你想把两个类放在一个表中......基类有什么问题,无论如何它感觉很适合你的情况?!跨度>
  • 如果您认为这些项目属于同一个表,那么它们具有共同的基本关系。
  • 因此,在两个类完全不相关且没有基类但巧合地实现完全相同的 IDictionary Dates 属性的情况下,最佳做法是将它们实际存储在两个单独的桌子?
  • 当然。为什么要拥有两个完全不相关的课程——这也意味着引用的日期完全不相关! - 与同一张桌子有关。这将是一个大泥球的特定配方。这些日期只是巧合的格式相同,但它们之间没有任何关系,因此在这种情况下它们必须放在单独的表格中。