我有一张桌子让我们打电话给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);
});
我需要如何正确地创造这种结合?
答案 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 ......和......