문제

nhibernate를 사용하여 클래스에서 컬렉션을 필터링하여 가능한 객체의 하위 집합 만 포함합니다. 아래에는 설명을 돕기 위해 샘플 테이블 데이터를 포함하고 있습니다. nhibernate를 사용하여 이것을 할 방법을 찾을 수 없습니다.

표 : dataObject

DataObjectid (pk) / name / currentversion

11          "data.txt"      2
12          "info.txt"      3

표 : dataObjectVersion

id / comment / versionnumber / dataObjectid (fk)

31   "Genesis"         1          11     <= Ignore this object
32   "Changed data"    2          11     <= Get this object
34   "Genesis"         1          12     <= Ignore this object   
35   "Changed info"    2          12     <= Ignore this object
36   "Added info"      3          12     <= Get this object

하나의 명령으로 각 dataObject에 대해 비 외국 키 dataObject.currentVersion = dataObjectVersion.versionNumber에 가입하고 싶습니다.

클래스 및 매핑 파일은 다음과 같습니다.

public class DataObject
{
  public virtual int DataObjectId { get; set; }
  public virtual string Name { get; set; }
  public virtual int CurrentVersionNumber { get; set; }
  public virtual IList<DataObjectVersion> Versions { get; set; }
}

<class name="DataObject" table="DataObject" lazy="false">
    <id name="DataObjectId" column="DataObjectId" type="int">
      <generator class="assigned" />
    </id>
    <property name="Name" column="Name" type="String(512)" />
    <property name="CurrentVersionNumber" column="CurrentVersionNumber" type="int" />
    <bag name="Versions" cascade="all-delete-orphan" inverse="true" lazy="false" >
        <key column="DataObjectId" />
        <one-to-many class="DataObjectVersion" />
    </bag>
</class>

public class DataObjectVersion
{
    public virtual int DataObjectVersionId { get; set; }
    public virtual string Comment { get; set; }
    public virtual int VersionNumber { get; set; }
    public virtual int DataObjectId { get; set; }
}

<class name="DataObjectVersion" table="DataObjectVersion" lazy="false">
    <id name="Id" column="DataObjectVersionId" type="int">
      <generator class="assigned" />
    </id>
    <property name="Comment" column="Comment" type="String(512)" />
    <property name="VersionNumber" column="VersionNumber" type="int" />
    <property name="DataObjectId" column="DataObjectId" type="int" />
</class>  
도움이 되었습니까?

해결책

주문형 수집을 필터링하려면 필터를 사용하는 것이 유효한 선택입니다. 버전 클래스와 백 요소 모두에서 필터를 선언하고 nhibernatessession.enableFilter 메소드에서 필터를 적용해야합니다.

가방에서 항상 단일 버전을 가져 오려면 가방 매핑에서 '여기서'를 구현하십시오.

<bag name="Versions" cascade="all-delete-orphan" inverse="true" lazy="false" where="CurrentVersionNumber = Versions.VersionNumber" >
    <key column="DataObjectId" />
    <one-to-many class="DataObjectVersion" />
</bag>

'여기서'에서 HQL이 아닌 적절한 SQL을 작성하고 위에 쓴 적절한 SQL은 아마도 스키마를 반영하기 위해 변경되어야 할 것입니다.

또한 단일 객체를 가져 오려면 가방을 설정하고 ILIST가 과잉 일 수 있습니다. 클래스에서 공식 속성과 DataObjectVersion 객체를 적용하는 것이 더 적절할 수 있습니다.

클래스 DataObject에서 ILIST를 대체하십시오

public virtual DataObjectVersion Version { get; set; }

그리고 매핑에서 '가방'을 라인의 무언가로 바꾸십시오.

<property name="Version" type="DataObjectVersion" update="false" insert="false" formula="(select v.DataObjectVersionId, v.Comments, v.VersionNumber, v.DataObjectId from DataObjectVersion v where v.VersionNumber  = CurrentVersionNumber)" />

다시 올바른 SQL 만 허용됩니다

나는 기본 데이터 유형 (dateTime, String 등)과 함께 계산 된 속성을 사용했으며 엔티티를 가져 오는 것은 점점 더 다른 것을 필요로 할 수 있습니다.

마지막으로, 컬렉션에 필터를 적용 할 수 있습니다. ~ 후에 컬렉션에 필터를 만들어 기본 객체 DataObject를 가져 왔습니다.

IList<DataObjectVersion>  fVersion = 
    NHibernateSession.CreateFilter(do.Versions, "where VersionNumber = :ver")
        .SetParameter("ver", do.CurrentVersionNumber)
        .List<DataObjectVersion>();

do.versions 컬렉션이 초기화되지 않은 경우, 별도의 Fversion 컬렉션에서 결과 만 가져오고 DataObject Fetch의 DB에 반대를 한 후 이미 두 번째 선택입니다.

다른 팁

아마도 사용자가 데이터를 변경하고 최신 데이터를 얻으려고 할 때 버전 번호가 증가 할 것입니다. versionnumber를 대신 "Age"필드로 간주하는 경우 (즉, 0은 최신 / 가장 어린 버전이고, 1은 다음으로 가장 오래된 버전이고) 문제가 0의 나이를 가진 모든 엔티티를 얻는 방법이됩니다. 필터를 사용하여 수행해야합니다. http://nhibernate.info/doc/nh/en/index.html#objectstate-filters

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