문제

현재 NHibernate를 데이터 액세 나는 Tripitem과 TripitemattributeValue의 두 가지 수업을 가지고 있으며, 그들 사이에 많은 관계가 있습니다.

매핑은 다음과 같습니다.

public class TripItemMap : ClassMap<TripItem2>
{
    public TripItemMap()
    {
        WithTable("TripItemsInt");
        NotLazyLoaded();

        Id(x => x.ID).GeneratedBy.Identity().WithUnsavedValue(0);
        Map(x => x.CreateDate, "CreatedOn").CanNotBeNull();
        Map(x => x.ModifyDate, "LastModified").CanNotBeNull();

        /* snip */

        HasManyToMany<TripItemAttributeValue>(x => x.Attributes).AsBag()
            .WithTableName("TripItems_TripItemAttributeValues_Link")
            .WithParentKeyColumn("TripItemId")
            .WithChildKeyColumn("TripItemAttributeValueId")
            .LazyLoad();
    }
}

public class TripItemAttributeValueMap : ClassMap<TripItemAttributeValue>
{
    public TripItemAttributeValueMap()
    {
        WithTable("TripItemAttributeValues");

        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name).CanNotBeNull();

        HasManyToMany<TripItem2>(x => x.TripItems).AsBag()
            .WithTableName("TripItems_TripItemAttributeValues_Link")
            .WithParentKeyColumn("TripItemAttributeValueId")
            .WithChildKeyColumn("TripItemId")
            .LazyLoad();
    }
}

내 응용 프로그램의 어느 시점에서 나는 데이터베이스에서 기존 속성을 가져와 tripitem.attributes에 추가 한 다음 tripitem 객체를 저장합니다. 결국, tripitems_tripitemattributevalues_link는 새로운 레코드를 얻지 못하므로 관계가 지속되지 않습니다.

도움이되면이 클래스에 대해 Fluent Nhibernate가 생성 한 매핑 파일입니다.

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" assembly="ETP.Core" namespace="ETP.Core.Domain">
  <class name="TripItem2" table="TripItemsInt" xmlns="urn:nhibernate-mapping-2.2" lazy="false">
    <id name="ID" column="ID" type="Int32" unsaved-value="0">
      <generator class="identity" />
    </id>
    <property name="CreateDate" column="CreatedOn" type="DateTime" not-null="true">
      <column name="CreatedOn" />
    </property>
    <property name="ModifyDate" column="LastModified" type="DateTime" not-null="true">
      <column name="LastModified" />
    </property>
    <bag name="Attributes" lazy="true" table="TripItems_TripItemAttributeValues_Link">
      <key column="TripItemId" />
      <many-to-many column="TripItemAttributeValueId" class="ETP.Core.Domain.TripItemAttributeValue, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
  </class>
</hibernate-mapping>

그리고

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" assembly="ETP.Core" namespace="ETP.Core.Domain">
  <class name="TripItemAttributeValue" table="TripItemAttributeValues" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" column="Id" type="Int32">
      <generator class="identity" />
    </id>
    <property name="Name" column="Name" length="100" type="String" not-null="true">
      <column name="Name" />
    </property>
    <bag name="TripItems" lazy="true" table="TripItems_TripItemAttributeValues_Link">
      <key column="TripItemAttributeValueId" />
      <many-to-many column="TripItemId" class="ETP.Core.Domain.TripItem2, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
  </class>
</hibernate-mapping>

여기서 내가 뭘 잘못하고 있니?

도움이 되었습니까?

해결책

@efdee

나는 같은 문제를 겪고 있었고 거의 이틀을 보냈습니다. 나는 많은 관계가 있었고 링크 테이블도 업데이트되지 않았습니다. 나는 nhibernate를 처음 접했고, 그냥 배우려고 노력하므로 소금 한 알로 내가 말하는 모든 것을 가져 가십시오.

글쎄요, 그것은 유창한 nhibernate 나 매핑이 아니라는 것이 밝혀졌지만, nhibernate가 다수의 방식으로 어떻게 작동하는지 이해하지 못했습니다. 두 엔티티의 컬렉션이 채워지지 않으면 다량의 관계에서 NHibernate는 링크 테이블에 데이터를 지속하지 않습니다.

이 엔티티가 다량의 관계에 있다고 가정 해 봅시다.


partial class Contact
{
   public string ContactName {get; set;}
   public IList Locations {get; set;}

}

partial class Location
{
   public string LocationName {get; set;}
   public string LocationAddress {get;set;}
   public IList Contacts {get;set;}
}

Contact.locations의 위치에 추가하면 접점이 위치에 있어야하는지 확인해야합니다.

따라서 위치를 추가하려면 연락처 클래스 내에이 방법이 있습니다.


public void AddLocation(Location location)
        {
            if (!location.Contacts.Contains(this))
            {
                location.Contacts.Add(this);
            }
            Locations.Add(location);
        }

이것은 내 문제를 해결 한 것으로 보이지만, 내가 말한 것처럼, 나는 단지 nhibernate를 집어 들고 그것을 배우고 있다면 더 좋은 방법 일 수 있습니다. 누군가가 더 나은 솔루션을 가지고 있다면 게시하십시오.

이것은 두 컬렉션을 모두 확인할 것을 지적한 게시물입니다. http://www.coderanch.com/t/217138/object-relational-mapping/link-table-of-manytomany-annotation

다른 팁

call session.flush () 또는 트랜잭션을 사용하십시오.

유창한 nhibernate로 어떻게하는지 잘 모르겠지만 가방에 캐스케이드 옵션을 설정해야합니다 (TripItems). 평소와 같이 Ayende 's는 캐스케이드 옵션에 대한 유용한 게시물을 얻었습니다.

빠른 Google에서 시도해 보겠습니다.

HasManyToMany<TripItem2>(x => x.TripItems).AsBag()
        .WithTableName("TripItems_TripItemAttributeValues_Link")
        .WithParentKeyColumn("TripItemAttributeValueId")
        .WithChildKeyColumn("TripItemId")
        .LazyLoad()
/*-->*/ .Cascade.All(); /*<-- this is the bit that should make it work */

나도 같은 문제가있었습니다. 다수의 결합 데이터는 지속되지 않았습니다. 나는 또 다른 다중 관계에서 매핑을 복사했지만 (다수의 관계를 위해 수정)는 "true"속성을 유지했습니다. 이 속성을 제거하면 문제가 해결되었습니다.

데이비드 켐프 (David Kemp)는 제대로가 있습니다. 가방에 캐스케이드를 추가하고 싶습니다.

나는 항상 매핑 파일을 손으로 편집하고 손으로 만들었습니다. 그래서 자연스럽게 성향은 그것을 거기에 두는 것입니다. 다음과 같이 할 수 있습니다.

<bag name="TripItems" lazy="true" table="TripItems_TripItemAttributeValues_Link" cascade="all">
  <key column="TripItemAttributeValueId" />
  <many-to-many column="TripItemId" class="ETP.Core.Domain.TripItem2, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>

.hbm.xml 파일의 NHibernate와 관련된 모든 내용을 '순수'하고 모든 것을 유지하면 솔루션이 클리너를 유지한다는 것을 알았습니다. 그렇게하면 사용하려는 새로운 ORM 소프트웨어가 있으면 매핑 파일을 교체하고 클래스를 다시 작성하지 않습니다. 유창한 nhibernate의 방법과 비슷하지만 단위 테스트를 사용하여 클래스를 테스트하고 XML에 테스트 할 수 있습니다.

나는 정확히 같은 문제를 겪고 있지만 nhibernate.jetdriver를 사용하고 있습니다. 나는 아무런 성공도없이 권장 답변을 사용해 보았습니다. nhibernate.jetdriver가 다수와 관련하여 제한이 있는지 아는 사람이 있습니까?

누군가가 잠시 검토에 관심이있는 경우 내 HBM 파일은 다음과 같습니다.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Ace.Docs.Core.Domain" assembly="Ace.Docs.Core">
<class name="Ace.Docs.Core.Domain.Address, Ace.Docs.Core" table="Addresses" lazy="true">
    <id name="Id" column="ID">
        <generator class="identity" />
    </id>
    <property name="Address1" column="Address1" />
    <property name="Address2" column="Address2" />
    <property name="City" column="City" />
    <property name="EmailAddress" column="EmailAddress" />
    <property name="Phone1" column="Phone1" />
    <property name="Phone2" column="Phone2" />
    <property name="PostalCode" column="PostalCode" />
    <property name="StateOrProvince" column="StateOrProvince" />
    <many-to-one name="AddressTypeMember" column="AddressTypeID" class="AddressType" />
    <bag name="HasPersonalInfo" table="Link_PersonalInfo_Addresses" lazy="true" cascade="save-update" inverse="true" >
        <key column="AddressID"></key>
        <many-to-many column="PersonalInfoID" class="PersonalInfo" />
    </bag>
</class>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Ace.Docs.Core.Domain" assembly="Ace.Docs.Core">
<class name="Ace.Docs.Core.Domain.PersonalInfo, Ace.Docs.Core" table="PersonalInfo" lazy="true">
    <id name="Id" column="ID">
        <generator class="identity" />
    </id>
    <property name="Prefix" column="Prefix" />
    <property name="FirstName" column="FirstName" />
    <property name="MiddleName" column="MiddleName" />
    <property name="LastName" column="LastName" />
    <property name="SIN" column="SIN" />
    <property name="Birthdate" column="Birthdate" />
    <property name="Note" column="Notes" />
    <bag name="HasAddress" table="Link_PersonalInfo_Addresses" lazy="true" cascade="save-update" inverse="true" >
        <key column="PersonalInfoID"></key>
        <many-to-many column="AddressID" class="Address" />
    </bag>
</class>

나는 그것을 얻었고 이것이 다른 사람을 도울 수 있기를 바랍니다. 문제는 두 가방 모두에 역 = 'true'가 있다는 것입니다. 아래의 발췌문을 읽으면 가방 중 하나에만 True로 설정되어 있어야합니다.

inverse = "true"의 사용에 유의하십시오. 다시 한 번,이 설정은 nhibernate에게 카테고리 수집에 대한 변경 사항을 무시하고 데이터베이스와 동기화되어야하는 표현으로서 협회의 다른 쪽 끝을 사용하도록 지시합니다.

Cascade.all ()가 실제로 내 문제에 대한 해결책이 아니라고 두려워합니다. 제가 시도한 것 중 하나였습니다. 문제는 컬렉션에 추가 된 항목이 저장되지 않았다는 것이 아니라 컬렉션에 추가 될 때 이미 데이터베이스에 있습니다. 링크 테이블의 항목이 만들어지지 않는 것입니다. 또한 Cascade.all ()은 아동 품목을 삭제하게 될 것이라고 생각합니다. 이는 시나리오에서 바람직하지 않은 행동이 아닙니다. Cascade.saveUpdate ()를 사용해 보았지만 내가 지적했듯이, 이것은 실제로 내 문제가 아닌 것을 해결합니다 :-)

그러나 확인하기 위해이 솔루션을 다시 시도하고 결과를 알려 드리겠습니다.

클래스를 순수하게 유지하면서, 이것은 유창한 nhibernate의 경우 100%입니다. 당신이 만든 클래스 매핑은 c# 코드 파일입니다.

나는 이것에도 어려움을 겪고 있었고, 내 문제에 대한 완전히 다른 이유가 생겼습니다. 내 예에서 내가 다수의 관계가없는 객체가 있다면 SaveorupDate에게 전화 할 수 있고 모두 좋을 것입니다. 그러나 많은 관계가 있다면 SaveorupDate 호출이 시작 추정 및 커밋 전환 내에 있는지 확인해야했습니다. 나는 유창한 nhibernate를 처음 접 했으므로 이것이 분명하다면 사과드립니다. 그러나 그것은 나에게 아니었다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top