Nhibernate多表与特定表有一对多的关系

时间:2014-03-20 17:40:37

标签: c# sql .net nhibernate

我有一张桌子让我们打电话给A. A有字段 - objId。

还有其他表格让我们调用B,C和D.它们有一个A记录列表。 需要通过将A记录添加到表B,C和D之一的A记录列表中来创建记录.objId字段需要是B / C / D记录的PK(id)谁拥有该列表A。

这意味着 - objId是许多表的FK。 我从表B开始。 但是在B表创建了表A创建的字段objId之后。现在表C和D会是什么?他们无法在表格中创建列objId。

代码是:  

<id name="Id">
  <generator class="guid" />
</id>

<bag name="As" cascade="All">
  <key column="ObjId" />
  <one-to-many class="A" />
</bag>

<class name="A">
<id name="Id">
  <generator class="guid" />
</id>
<property name="ObjId" />

public class B
{
    public virtual Guid Id { get; set; }
    public virtual IList<A> As{ get; set; }
}

public class A
{  
    public virtual Guid Id { get; set; }
    public virtual string ObjId { get; set; }
}

将记录添加到B:

       this.Update(session =>
       {
           var bRecord = ....;

           bRecord.As.Add(new ARecord {
                 ...
          });

             session.Update(bRecord);
       });

我需要如何正确地创造这种结合?

1 个答案:

答案 0 :(得分:0)

一般来说,有更多方法可以处理这种情况 - 每种方法都需要进行一些调整/扩展。即你必须改变你的数据库结构

如果每个B,C,D都可以引用 A 的实例,那么唯一的方法就是引入外键列BObjectId,CObjectId,DObjectId。

如果A的实例可以由其中一个(B,C,D)专门使用,我们需要新列,我们称之为Discriminator

<class name="A">
  <id name="Id" generator="guid" />
 <property name="ObjId" />
 <property name="Discriminator" />
</class>

现在,我们必须在C#代码中正确填写Discriminator中的值。如果A被分配给B,我们必须填写&#39; B&#39;

var a = new A();
b.AddA(a);

执行应该是这样的。

public virtual void AddA(A a)
{
    As.Add(a);
    a.ObjectId = this.ID
    a.Discriminator = 'B'
}

注意:在这种情况下,我们会将ID分配到ObjectId。它正在工作,但仅在已分配ID时才有效。如果对象B是暂时的,具有默认ID值,它将无法工作。在这种情况下,我们需要创建一些解决方法。例如。刷新()B然后分配参考...

因此,我们成功地将Discriminator值正确地管理/填充/插入到A实例/记录中。现在我们也可以将它用于映射。 B,C,D袋映射将非常相似:

<class name="A">
  <bag name="As" cascade="All" batch-size="25"
    where=" Discriminator = 'B' " >
      <key column="ObjId" />
      <one-to-many class="A" />
  </bag>

where=" Discriminator = 'B' "是NHibernate如何将过滤器注入我们的集合的好方法。适用于C,D ......和......