0

名前付き HQL クエリを使用していた状況がありますが、DAL が変更されたので、Linq で名前付きクエリをやり直す方法がわかりません。読み込まれる HolterTest というエンティティがあります。その HolterTest を含む WorkItem を作成する必要があるため、そのためには、WorkItem をまだ持っていない既存の HolterTests をすべて見つける必要があります。それらに関連付けられています。

元の HQL 名前付きクエリは次のとおりです。

<query name="Get.HolterTests.Without.WorkItems" >
<![CDATA[ from HolterTest as ht
          where not exists (from WorkItem as wi
          where wi.HolterTest.ID = ht.ID) 
          and ht.RecordingStartDateTime == null]]>
</query>

WorkItem エンティティの NHibernate マッピングは次のとおりです。

<class name="WorkItem" table="WorkItems" where="" dynamic-update="true" dynamic-insert="true" >
<id name="ID" column="WorkItemID" type="Int32" >
  <generator class="identity"/>
</id>

<property name="Status"  type="AnsiString" />
<property name="IsCompleted"  />
<property name="IsStarted" />    
<property name="CompletedDateTime" type="DateTime" />
 <many-to-one name="HolterTest" lazy="false" class="HolterTest" column="HolterTestID" unique="true" not-null="true" cascade="save-update"/>

<bag name="WorkTasks" cascade="all-delete-orphan" inverse="true" lazy="false"  >
  <key column="WorkItemID" on-delete="cascade" />
  <one-to-many class="HolterManagementBackend.Domain.Models.WorkTask"/>
</bag>

これは HolterTest オブジェクトのマッピング ファイルで、1 対 1 のマッピングがあります。

  <class name="HolterTest" table="HolterTests" where="" dynamic-update="true" dynamic-insert="true">
<id name="ID" column="HolterTestID" type="Int32" >
  <generator class="identity"/>
</id>

<property name="MayoClinicNumber" type="AnsiString" />
<property name="HolterTestType" type="Int32" />
<property name="LastName"  type="AnsiString" />
<property name="RecordingStartDate"  type="DateTime" not-null="false" />
<property name="HookUpApptDate" type="DateTime" not-null="false" />
<property name="FollowupApptDate" type="DateTime" not-null="false" />
<property name="Room" type="AnsiString" />
<property name="HolterUnitSerial" type="AnsiString" />
<property name="HookupTechLanID" type="AnsiString" />
<property name="OrderingMDLanID" type="AnsiString" />
<property name="ReviewingMDLanID" type="AnsiString" />

<one-to-one name="WorkItem" lazy="false" class="WorkItem" property-ref="HolterTest" cascade="save-update" />

<many-to-one name="Location" class="Location" column="LocationID"  not-found="ignore" fetch="join" lazy="false"/>

私の DAL のリワークでは、Linq を使用するための抽象クラスの仕様ができました。

namespace HolterManagementBackend.DAL.Contracts
{
public abstract class Specification<T>
  {
    public abstract Expression<Func<T, bool>> MatchingCriteria { get; }

    public T SatisfyingElementFrom(IQueryable<T> candidates)
    {
        return SatisfyingElementsFrom(candidates).Single();
    }

    public IQueryable<T> SatisfyingElementsFrom(IQueryable<T> candidates)
    {
        return candidates.Where(MatchingCriteria).AsQueryable();
    }

  }
}

これは、DAO オブジェクトの FindAll メソッドで使用されます。

    /// <summary>
    /// finds all the objects which match the specification expression provided
    /// </summary>
    /// <param name="query">the expression to search on</param>
    /// <returns>all the objects that match the criteria</returns>
    [Transaction( ReadOnly = true)]
    public IList<T> FindAll(Specification<T> query)
    {
        return query.SatisfyingElementsFrom(SessionFactory.GetCurrentSession().Query<T>()).ToList();
    }

これは、HookupApptDate 範囲を使用して、特定の地域のすべての HolterTests を取得するための、より単純な仕様です。

public class GetHolterTestToHookUpByRegionID : Specification<HolterTest>
{
    private readonly int _days;
    private readonly int _regionId;

    public GetHolterTestToHookUpByRegionID(int regionId, int numberOfDays)
    {
        _days = numberOfDays;
        _regionId = regionId;
    }

    public override Expression<Func<HolterTest, bool>> MatchingCriteria
    {
        get
        {
            return x => x.HookUpApptDate <= Convert.ToDateTime(System.DateTime.Today.AddDays(_days))
                && x.Location.Region.ID == _regionId && x.RecordingStartDate == null;
        }
    }

}

どうすればよいかわからないのは、NotExists と結合を含む仕様を作成することです。提案/アイデアはありますか?

更新: 1 対 1 では、RecordingStartDate が null であるすべての HolterTest オブジェクトを取得すると、ループして WorkItem が null のオブジェクトを見つけることができますが、x.WorkItem == null をクエリに入れようとすると仕様、何も返ってきません。

4

1 に答える 1

1

HolterTestという名前のコレクション プロパティを指定WorkItemsし、何も含まれていないことを確認します。

x.RecordingStartDate == null && !x.WorkItems.Any()
于 2013-05-14T17:53:42.907 に答える