簡體   English   中英

如何在NHibernate中使用CompositeId級聯保存?

[英]How to cascade Save with CompositeId in NHibernate?

我有一個簡單的三表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?

更新:

為清楚起見,我刪除了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);

謝謝!

我確實在nhibernate用戶組問了這個問題。 答案是沒有辦法使用composite-id級聯任何操作(可能在將來的版本中它是可能的)。

所以我做了一個解決方法。 我放置了兩個引用(多個一對一的級聯)而不是CompositeId,並將Id添加到AB表和AB實體。 現在它正在工作,A和B實體正在級聯。

只是旁注,但為什么要創建AB類? 如果這兩個類之間的關系沒有任何額外的屬性,那么你的班級'AB'就沒有必要......

回答你的問題:你可以在NHibernate中的關系上定義級聯選項。

在Fluent NHibernate中,我想你必須這樣做:

public class FooMap : ClassMap<Foo>
{
    public FooMap()
    {
       HasMany(x => x.Bars).Cascade.AllDeleteOrphan();
    }
}

(請注意,您必須將其應用於您的情況,但collectionmapping返回屬性Cascade,因此您可以定義要應用的級聯技術)

我實際上設法讓它很容易工作,代碼看起來太多了,不干!

這是我的案例:

public class MappingSample : ClassMap<DomainClass>
{
    public MappingCvTheme()
    {
        CompositeId()
            .KeyProperty(x => x.SomeProperty)
            .KeyReference(x => x.SomeReferencedObjectProperty);

        //here comes the trick, repeat the reference code:
        References(x => x.SomeReferencedObjectProperty).Cascade.All();
    }
}

我希望它有助於某人在將來尋找同樣的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM