문제

나는 다수의 관계를 가진 간단한 3 개의 테이블 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 */ }
}

나는 유창한 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 나는 얻는다 과도하여. 그래서 그것을 넘겨주기 위해서는 필요합니다 SaveorUpdate AB를 저장하기 전에 A와 B. 그러나이 물체들을 단일로 유지하는 다른 방법이있는 것 같습니다. SaveorUpdate.

AB 매핑을 가리키는 방법이 있습니까? 종속 저장 작업에서 A와 B?

업데이트:

명확성을 위해 클래스에서 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 대신 두 개의 참고 문헌 (캐스케이드가있는 다중 하나)을 배치하고 AB 테이블 및 AB 엔티티에 ID를 추가했습니다. 이제 작동 중이며 A와 B 엔티티가 계단식을하고 있습니다.

다른 팁

단지 부수적이지만 왜 클래스 AB를 만들었습니까? 이 두 클래스 사이의 관계에 추가 속성이 없으면 클래스 'AB'가 필요하지 않습니다 ...

질문에 답하기 위해 : nhibernate의 관계에서 캐스케이드 옵션을 정의 할 수 있습니다.

유창한 nhibernate에서는 다음과 같이해야 할 것 같아요.

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

(상황에 적용해야하지만 CollectionMapping은 속성 캐스케이드를 반환하므로 적용하려는 계단식 기술을 정의 할 수 있습니다).

나는 실제로 그것을 매우 쉽게 작동하게 만들었고, 코드는 너무 건조하지 않은 것처럼 보입니다!

내 사례는 다음과 같습니다.

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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top