3

Person、Employee1、Employee2 の 3 つのクラスがあります。

public class Employee1 : Person
{
}

public class Employee2 : Person
{
}

Employee1_Table または Employee_Table に参加する必要があるという Person_Table のクエリが必要です。

var q = SessionInstance.Query<Person>();

if (dto.Code != null)                           // A1 Condition
     q = q.Where(x => x.Code == dto.Code);

//if(A2 Condition)
//if(A3 Condition)
//...

switch (dto.Type)
{
    case PersonType.Employee1:
         var q1 = SessionInstance.Query<Employee1>();
         q.Join(q1, x => x.Id, xx => xx.Id, (x, xx) => x);

         if (!String.IsNullOrEmpty(dto.Unit))   // B1 Condition
             q1 = q1.Where(xx => xx.Unit == dto.Unit);

         //if(B2 Condition)
         //if(B3 Condition)
         //... 

         return q1.ToList<Person>();

    case PersonType.Employee2:
         var q2 = SessionInstance.Query<Employee2>();
         q.Join(q2, x => x.Id, xx => xx.Id, (x, xx) => x);

         if (!String.IsNullOrEmpty(dto.Serial)) // C1 Condition
             q2 = q2.Where(xx => xx.Serial == dto.Serial);

         //if(C2 Condition)
         //if(C3 Condition)
         //... 

         return q2.ToList<Person>();

    default:
         return q.ToList();
}

この結合のクエリは不完全です。dto.TypeがPersonType.Employee1またはPersonType.Employee2と等しい場合、A1 , A2 , ...影響しません。ただし、スイッチのデフォルトのケースでA1 , A2 , ...は、クエリに影響があります。3 つの別々のクラスの Where 条件が多く、Whereクエリの条件を別々に追加する必要があります。なんで?

アップデート :

var q = SessionInstance.Query<Person>();

if (dto.Code != null)                           // A1 Condition
     q = q.Where(x => x.Code == dto.Code);

//if(A2 Condition)
//if(A3 Condition)
//...

 var q1 = SessionInstance.Query<Employee1>();

 if (!String.IsNullOrEmpty(dto.Unit))   // B1 Condition
     q1 = q1.Where(xx => xx.Unit == dto.Unit);

 //if(B2 Condition)
 //if(B3 Condition)
 //... 

 return q.Join(q1, x => x.Id, xx => xx.Id, (x, xx) => x).ToList<Person>();

B1条件が true の場合、この更新されたクエリには例外があります。この例外のメッセージ:指定されたメソッドはサポートされていません。

スタック トレースは次のとおりです。

   at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource)
   at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree)
   at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process()
   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
   at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
   at NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression)
   at Remotion.Data.Linq.QueryableBase`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
4

1 に答える 1

6

デフォルト以外のスイッチの場合、それぞれ q1 と q2 を返します。これらのクエリには、q を含むものは割り当てられません。これが、最終的なクエリに Ax 条件が存在しない理由を説明しています。

また、次の行を検討してください。

q.Join(q1, x => x.Id, xx => xx.Id, (x, xx) => x);

すべての LINQ メソッドと同様に、Join メソッド() は q または q1 にまったく影響を与えませんが、代わりに新しい IQueryable を返します。記述されたコードはこの戻り値を無視するため、この行は最終的なクエリには影響しません。

他のどこでも正しいパターンがあります。つまり、「q = q.Something ....」です。

Join() を変更して、最後のパラメーターで新しい {x, xx} を返すようにする必要があります。これにより、.Where() 呼び出しを q1 から q に移動しても、q1 からアイテムにアクセスできるようになります。何かのようなもの:

var qJoined = q.Join(SessionInstance.Query<Employee1>(),
                     x => x.Id, xx => xx.Id,
                     (x, xx) => new {x, xx});

if (!String.IsNullOrEmpty(dto.Unit))   // B1 Condition
    qJoined = qJoined.Where(w => w.xx.Unit == dto.Unit);

return qJoined.Select(w => w.x).ToList();
于 2013-01-20T15:12:42.767 に答える