如何级联保存在NHibernate的CompositeId? [英] How to cascade Save with CompositeId in NHibernate?

查看:169
本文介绍了如何级联保存在NHibernate的CompositeId?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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 * /}
}

我已经与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆