2011-01-06 7 views
1

Nhibernateを使用してデータをフィルタリングする一般的なソリューションに取り組んでいます。このUnfortunatley汎用データグリッドフィルタリング

private ICriteria GetPagedCriteria<T>(GridResult<T> GridResult, bool sort) 
     { 
      var query = Session.CreateCriteria(typeof(T)); 

      foreach (string alias in GridResult.NHibernatePaths) 
      { 
       query.CreateAlias(alias, alias.Replace(".", "_")); 
      } 

      foreach (PropertyValueOperators pvo in GridResult.FilterList) 
      { 
       if(String.IsNullOrEmpty(pvo.Value) == false) 
       { 
        switch (pvo.LikeOperator) 
        { 
         case "Contains": 
          query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), String.Format("%{0}%",pvo.Value), MatchMode.Exact)); 
         break; 
         case "EndsWith": 
          query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), String.Format("%{0}", pvo.Value), MatchMode.Exact)); 
         break; 
         case "Equals": 
          query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), pvo.Value, MatchMode.Exact)); 
         break; 
         case "Starts With": 
          query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), String.Format("{0}%", pvo.Value), MatchMode.Exact)); 
         break; 
         default: 
          throw new ArgumentException("LikeOperator not recognised"); 
        } 
       } 
      } 

      if (sort) 
      { 
       foreach (var pair in GridResult.SortList) 
       { 
        var func = pair.Value 
         ? new Func<string, NHibernate.Criterion.Order>(NHibernate.Criterion.Order.Asc) 
         : new Func<string, NHibernate.Criterion.Order>(NHibernate.Criterion.Order.Desc); 
        query.AddOrder(func(pair.Key)); 
       } 
      } 

      return query; 
     } 

が「好き」がたくさんあり、非常に非効率的である「キャスト」でSQLを作成します。コードは次のようになります。私が知っていることを期待する...私はまだNHibernateの専門家ではないので、このジェネリックソリューションをより効率的にするためにコメントをいただければ幸いです。事前に多くの感謝。

クリスチャン

答えて

1

はEndswithとSTARTSWITHのようなことなく、SQLで同様のものに変換することはできません、が含まれています。 SQLデータベースは、こうした種類のクエリには適していません。あなたはより良いあなたのケースでの演算子のように使用しないようにする方法方法はありませんNHiberante.Search

+0

ありがとうPaco - 私はそう思った。私は今のところこれで生きなければならないと思う。 "Equals"ビットを改善したいと思います。 1つのアイデアは、プロパティの型を決定し、値の型が同じであるかどうかをチェックしてから、Restrictions.Eqを使用することです。プロパティのnhibernate/.netタイプを決定する簡単な方法はありますか?ありがとう。 – cs0815

+0

.net reflectionによる? – Paco

+0

上記の汎用コードが与えられた場合、どうすればよいでしょうか?ありがとう。 – cs0815

2

と組み合わせて、Luceneのような検索データベースを使用することができます。 まあ、均等オペレータは、 シンプルですがそれは、あまりにも、「『値%』のような」効率的になるために翻訳者である、それはサイド試合を残しているし、それがインデックスを使用することができるので、 は「を含む」と「で終わる「で始まります」すでに実装されているような操作に変換する必要があります。

あなたは本当にあなたが近づい変更する必要のようなベースさがす回避したい場合 - CriteriaAPIを使用し、より良いあなたのニーズにマッチかもしれないNHibernate.SearchでLucene.NETを使いません。私はそれらをプロダクションプロジェクトで使用しませんでしたが、完璧に見えます。