nhibernate에서 compositeid로 저장하는 방법은 무엇입니까?
-
07-07-2019 - |
문제
나는 다수의 관계를 가진 간단한 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();
}
}
미래에 같은 문제를 찾는 사람이 도움이되기를 바랍니다.