2011-01-06 9 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와 결합 된 Lucene과 같은 검색 데이터베이스를 더 잘 사용할 수 있습니다.

+0

고마워 Paco - 나는 그렇게 생각했다. 나는 지금 이걸 가지고 살아야 할 것 같아. "Equals"비트를 개선하고 싶습니다. 하나의 아이디어는 속성의 유형을 결정하고 값의 유형이 같은지 확인한 다음 사용하는 것입니다 : Restrictions.Eq. nhibernate/.net 유형의 속성을 결정하는 간단한 방법이 있습니까? 감사. – cs0815

+0

.net reflection? – Paco

+0

위의 일반적인 코드를 감안할 때 어떻게 할 수 있습니까? 감사. – cs0815

2

같은 연산자를 사용하는 것을 피하는 방법은 없습니다. 음, 등호 연산자가 간단합니다. "와 같은 '값 %'에 대한 번역기는 왼쪽 일치이고 인덱스를 사용할 수 있기 때문에 효율적입니다. "포함 "및"끝 " "이미 구현 한 것처럼 작업에 맞게 변환해야합니다.

당신이 정말로 당신이 접근 변경해야 같은 기반 seach을 피하려면

은 - CriteriaAPI을 사용하고 더 나은 귀하의 요구에 일치 할 수있는 NHibernate.Search와 Lucene.NET을 사용하지 마십시오. 프로덕션 프로젝트에서는 사용하지 않았지만 완벽 해 보였습니다.