2011-01-21 17 views
1

nHibernateとQueryOverを使用してList()の汎用メソッドを作成したいと思います。私はジョインを追加したいと思っていますが、私が参加しているジェネリック型を指定せずにはできないとは思いません...すべてのジェネリック宣言を宣言しなければならないので、ダイナミックにしません。動的なジョインリストをどこにも持っていますか?以下のコード:nHibernate DynamicOn with QueryOver

public static IList<T> QueryOver<T>(
     Dictionary<Expression<Func<T, object>>, JoinType> joins, 
     List<Expression<Func<T, bool>>> predicates, 
     Dictionary<Expression<Func<T, object>>, System.Web.UI.WebControls.SortDirection> sortList, 
     int? maxResults 
    ) where T : class 
    { 
     IList<T> results; 
     IQueryOver<T, T> query; 

     results = null; 

     // open the session 
     using (ISession session = OpenSession()) 
     { 
      // begin a transaction 
      using (ITransaction transaction = session.BeginTransaction()) 
      { 
       try 
       { 
        // declare the query 
        query = session.QueryOver<T>(); 

        // joins 
        if (joins != null && joins.Count > 0) 
        { 
         foreach (KeyValuePair<Expression<Func<T, object>>, JoinType> join in joins) 
         { 
          // required to specify the type in the format query.JoinQueryOver<SubType>(join.Key, join.Value) 
          // BUT this means that it's not so dynamic because each SubType would have to be specified in the method call, yes? 
          query = query.JoinQueryOver(join.Key, join.Value); 
         } 
        } 

        // apply the where clauses 
        if (predicates != null && predicates.Count > 0) 
        { 
         foreach (Expression<Func<T, bool>> predicate in predicates) 
         { 
          query = query.Where(predicate); 
         } 
        } 

        // apply the sorting 
        if (sortList != null && sortList.Count > 0) 
        { 
         foreach (KeyValuePair<Expression<Func<T, object>>, System.Web.UI.WebControls.SortDirection> sort in sortList) 
         { 
          if (sort.Value == System.Web.UI.WebControls.SortDirection.Ascending) 
          { 
           query = query.OrderBy(sort.Key).Asc; 
          } 
          else 
          { 
           query = query.OrderBy(sort.Key).Desc; 
          } 
         } 
        } 

        // max results 
        if (maxResults.HasValue && maxResults.Value > 0) 
        { 
         query = (IQueryOver<T, T>)query.Take(maxResults.Value); 
        } 

        results = query.List(); 

        // no errors, commit the transaction 
        transaction.Commit(); 
       } 
       catch (Exception ex) 
       { 
        // error, rollback 
        transaction.Rollback(); 

        // throw the exception and let the business logic deal with it 
        throw ex; 
       } 
      } 
     } 

     return results; 
    } 

答えて

1

JoinQueryOverの代わりにJoinAliasを使用して調べてください。

タイプTのエンティティに対するダイレクトジョインと間接ジョイン(2つ以上のステップイン)の2種類のジョインがあります。これらには異なるアプローチが必要です。

直接はに参加するために(1)、あなたのメソッドは、型のIEnumerableを(そのための準備を)受け取ることができます:

Tuple<Expression<Func<T, object>>, Expression<Func<object>>> 
の例は、呼び出し元のコードに次のようになります

JoiningEntity joiningEntity = null; 
new Tuple<Expression<Func<YourEntityType, object>>, Expression<Func<object>>>(entity => entity.JoiningEntity,() => joiningEntity) 

nullオブジェクトは、QueryOverで解決できるように単なるエイリアスです。 Visual Studioの警告では、nullであることを伝えて迷惑をかけることがあります。そのため、ヘルパーメソッドを使用してnullオブジェクトを作成します。 Null.Get<HolidayOccupancyPrice>()(Nullヘルパーメソッドの下部を参照)。間接的のために

(2)参加し、あなたはタイプのIEnumerableを渡す必要があります。

Tuple<Expression<Func<object>>, Expression<Func<object>>> 

すなわち、上記のようなもので、エンティティタイプなし。

IEnumerable<Tuple<Expression<Func<T, object>>, Expression<Func<object>>>> directJoins; 
IEnumerable<Tuple<Expression<Func<object>>, Expression<Func<object>>>> indirectJoins; 
// .... 
foreach (var join in directJoins) 
    query = queryable.Left.JoinAlias(dependency.Item1, dependency.Item2); 
foreach (var join in indirectJoins) 
    query = queryable.Left.JoinAlias(dependency.Item1, dependency.Item2); 

は(私は左が参加する指定した注意:クエリの方法で一緒にそれを置く

JoiningEntity joiningEntity = null; 
new Tuple<Expression<Func<object>>, Expression<Func<object>>>(() => joiningEntity.IndirectJoiningEntity,() => joiningEntity) 

は、あなたがこのような何かをしたいと思います。そして、あなたの呼び出し元のコードは次のように参加を送信することがあります明示的に - これを制御可能にしたい場合は、それをタプルの追加パラメータとして追加する必要があります)

これはかなり複雑に見えますが、一度まとめればそれほど単純です。もちろん、ヘルパーメソッドを作成してコード内の 'Func'の量を減らすことができます。

希望に役立ちます!


ヌルヘルパーメソッド:

public static class Null 
{ 
    public static T Get<T>() 
    { 
     return default(T); 
    } 
} 
関連する問題