2011-01-06 4 views
1

Ich habe an einer generischen Lösung gearbeitet, um Daten mit Nhibernate zu filtern. Der Code sieht wie folgt aus:generische Datengitter Filterung

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; 
     } 

Unfortunatley dies schafft SQL mit viel ‚mag‘ und ‚wirft‘, was sehr ineffizient ist. Zu erwarten, dass ich weiß ... Ich bin noch kein NHibernate-Experte und würde mich über Kommentare freuen, die diese generische Lösung effizienter machen. Vielen Dank im Voraus.

Christian

Antwort

1

enthält, EndsWith und Starts kann nicht ohne, wie ähnlich in SQL etwas umgewandelt werden. Eine SQL-Datenbank ist nicht ideal für diese Art von Abfragen. Sie können besser eine Suchdatenbank wie Lucene verwenden, kombiniert mit NHiberante.Search

+0

Danke Paco - ich dachte schon. Ich denke, ich werde jetzt damit leben müssen. Ich möchte das Bit "Gleich" verbessern. Eine Idee besteht darin, den Typ der Eigenschaft zu bestimmen und zu überprüfen, ob der Typ des Werts derselbe ist, und dann zu verwenden: Restrictions.Eq. Gibt es eine einfache Möglichkeit, den nhibernate/.net-Typ einer Eigenschaft zu bestimmen? Vielen Dank. – cs0815

+0

Durch .net Reflexion? – Paco

+0

Angesichts der oben genannten generischen Code - wie würden Sie das tun? Vielen Dank. – cs0815

2

Es gibt keine Möglichkeit, wie Sie in Ihrem Fall wie Operatoren zu verwenden vermeiden. Nun, Gleicher Operator ist einfach, "Beginnt mit" das ist Translater zu "wie 'Wert%'" wird auch effizient sein, da es linksseitige Übereinstimmung ist und Index verwenden kann, "enthält" und "endet mit "müssen in ähnliche Operationen übersetzt werden, wie Sie bereits implementiert haben.

Wenn Sie die like-basierte Suche wirklich vermeiden möchten, müssen Sie Ihre Herangehensweise ändern - verwenden Sie CriteriaAPI nicht und verwenden Sie Lucene.NET mit NHibernate.Search, das möglicherweise Ihren Anforderungen besser entspricht. Ich habe sie nicht im Produktionsprojekt verwendet, aber sie scheinen perfekt zu sein.