如何级联保存在NHibernate的CompositeId? [英] How to cascade Save with CompositeId in NHibernate?
问题描述
A(id,Name)$ b我有一个简单的三表格DB与多对多的关系。 $ b B(id,Name)
AB(AId,BId)引用A和B
相应的类:
public class A
{
public virtual int Id {get;组; }
public virtual string Name {get;组; }
}
public class B
{
public virtual int Id {get;组; }
public virtual string Name {get;组; }
}
public class AB
{
public virtual A A {get;组; }
public virtual B B {get;组; }
public override bool Equals(object obj){/ * routine * /}
public override int GetHashCode(){/ * routine * /}
}
$ c
我已经与Fluent NHibernate进行了映射:
$ $ p $ code> public class AMap:ClassMap< A>
{
public AMap()
{
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Name);
}
}
public class BMap:ClassMap< B> {/ *与A * /}相同
公共类ABMap:ClassMap< AB>
{
public ABMap()
{
CompositeId()
.KeyReference(x => xA,AId)
.KeyReference(x => xB,BId);
$ b所以现在我想能够做一些像这
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之前保存更新 A和B.但似乎应该有另一种方法来将这些对象保存在一个单独的SaveOrUpdate中。
是否有任何方法指向AB映射到级联 A和B上保存操作?
更新:
为了清楚起见,我删除了A类中的AB链接列表。原来是:
public class A
{
public A()
{
LinkToB = new List< AB>();
}
public virtual int Id {get;组; }
public virtual string Name {get; set}
公共虚拟IList< AB> LinkToB {get;私人设置}
}
公共类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();
//在交易中
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);
谢谢!
解决方案我在nhibernate用户组中问过这个问题。答案是,没有办法使用composite-id级联任何操作(也许在将来的版本中可能)。
所以我做了一个解决方法。我放置了两个引用(与级联多对一)而不是CompositeId,并将Id添加到AB表和AB实体。现在它正在工作,A和B实体级联。
I have a simple three table DB with many-to-many relation.
A(id, Name)
B(id, Name)
AB(AId, BId) references A and B
The corresponding classes:
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 */ }
}
I have made mappings with 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");
}
}
So now I want to be able to do something like this
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);
But on SaveOrUpdate I do get TransientObjectException. So to pass over it I need to SaveOrUpdate A and B before saving the AB. But it seems that there should be the other way to persist these objects in a single SaveOrUpdate.
Is there any way to point in AB mapping to Cascade A and B on save operation?
UPDATE:
I removed the List of AB links in A class for clarity. Originally it was:
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);
Thank you!
解决方案 I did ask this question at nhibernate user group. And the answer was that there is no way to cascade any operation using composite-id (maybe in the future releases it will be possible).
So I made a workaround. I placed two References (many-to-one with cascading) instead of CompositeId and added Id to the AB table and AB entity. Now it's working and A and B entities are cascading.
这篇关于如何级联保存在NHibernate的CompositeId?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!