我有一个简单的三表DB,具有多对多的关系 .
A(id, Name)
B(id, Name)
AB(AId, BId) references A and B
相应的课程:
public class A
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class B
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class AB
{
public virtual A A { get; set; }
public virtual B B { get; set; }
public override bool Equals(object obj) { /* routine */ }
public override int GetHashCode() { /* routine */ }
}
我已经使用Fluent NHibernate进行了映射:
public class AMap : ClassMap<A>
{
public AMap()
{
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Name);
}
}
public class BMap : ClassMap<B> { /* The same as for A */ }
public class ABMap : ClassMap<AB>
{
public ABMap()
{
CompositeId()
.KeyReference(x => x.A, "AId")
.KeyReference(x => x.B, "BId");
}
}
所以现在我希望能够做到这样的事情
var a = new A { Name = "a1" };
var b = new B { Name = "b1" };
var ab = new AB { A = a, B = b };
//session.SaveOrUpdate(a);
//session.SaveOrUpdate(b);
session.SaveOrUpdate(ab);
但是在SaveOrUpdate上,我确实得到了TransientObjectException . 因此,为了传递它,我需要在保存AB之前SaveOrUpdate A和B.但似乎应该有另一种方法将这些对象保存在单个SaveOrUpdate中 .
在保存操作中,是否有任何方法可以将AB映射指向级联A和B?
UPDATE:
为清楚起见,我删除了A类中的AB链接列表 . 最初它是:
public class A
{
public A()
{
LinkToB = new List<AB>();
}
public virtual int Id { get; set; }
public virtual string Name { get; set }
public virtual IList<AB> LinkToB { get; private set; }
}
public class AMap : ClassMap<A>
{
public AMap()
{
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Name);
HasMany(x => x.LinkToB)
.KeyColumn("AId")
.Inverse()
.Cascade.All()
.AsBag();
}
}
// inside the transaction
var a = new A { Name = "a1" };
var b = new B { Name = "b1" };
a.LinkToB.Add(new AB { A = a, B = b });
// session.SaveOrUpdate(b);
session.SaveOrUpdate(a);
谢谢!
3 回答
我确实在nhibernate用户组问了这个问题 . 答案是没有办法使用composite-id级联任何操作(可能在将来的版本中它是可能的) .
所以我做了一个解决方法 . 我放置了两个引用(多个一对一的级联)而不是CompositeId,并将Id添加到AB表和AB实体 . 现在它正在工作,A和B实体正在级联 .
只是旁注,但为什么要创建AB类?如果这两个类之间的关系没有任何额外的属性,那么你的 class 'AB'就没有必要......
回答你的问题:你可以在NHibernate中的关系上定义级联选项 .
在Fluent NHibernate中,我想你必须这样做:
(请注意,您必须将其应用于您的情况,但collectionmapping返回属性Cascade,因此您可以定义要应用的级联技术)
我实际上设法让它很容易工作,代码看起来太多了,不干!
这是我的案例:
我希望它有助于某人在将来寻找同样的问题 .