2010-01-22 4 views
3

J'essaie de retourner toutes les entités où une propriété donnée n'est pas vide. Le problème est IsNotEmpty() s'applique uniquement aux collections. Voici l'approche générale que j'ai prise jusqu'à présent, cela ne marche évidemment pas.Nhibernate ICriteria - Vérifier la valeur de la propriété longueur

ICriteria lvCriteria = NHibernateHelper.GetCurrentSession() 
             .CreateCriteria(typeof(FunctionCall)) 
             .SetMaxResults(100) 
             .AddOrder(Order.Desc("LogId")); 

if (pvMsg.HasValue) 
{     
     lvCriteria.Add(Restrictions.IsNotNull("Msg")) 
       .Add(Restrictions.IsNotEmpty("Msg")); 
} 

Des suggestions? Est-il possible d'atteindre ce résultat en vérifiant la longueur de la valeur de la propriété? Je vous remercie!

+0

Je ne comprends pas votre code ou je ne comprends pas ce qui est évident sur ce qui ne fonctionne pas. Pouvez-vous fournir des exemples de données d'entrée et quelques exemples de résultats (attendus et réels)? –

+0

Msg est simplement un champ de texte qui peut être vide, nul ou contenir une certaine valeur. Je voudrais retourner seulement ces entités "FunctionCall" dont la propriété Msg contient une certaine valeur. IsNotEmpty() s'applique uniquement aux collections, pas aux entités individuelles. (c'est-à-dire qu'il retourne vrai si une liste contient des éléments, mais lève une exception si elle est utilisée sur une seule propriété). Étant donné 3 entités FunctionCall avec 3 valeurs séparées "", null, et "ERROR" pour la propriété Msg, je ne m'attendrais qu'à une seule entité renvoyée par ma requête, celle qui contient "ERROR". – alan

Répondre

4

Finalement, j'ai découvert la combinaison que je cherchais!

lvCriteria.Add(Restrictions.Not(Expression.Eq("Msg", string.Empty))); 

Cette combinaison de restrictions et d'expressions fonctionne comme prévu; rétrécissant toutes les chaînes vides. Je ne sais pas pourquoi je ne pourrais pas obtenir ces résultats plus tôt, même avec:

lvCriteria.Add(Restrictions.Not(Restrictions.Eq("Msg", string.Empty))); 

Merci à tous ceux qui a essayé.

+0

Parfait. Je suis nouveau à NHibernate et je me demandais pourquoi je ne pouvais pas faire '.IsNotEmpty' comme prévu et maintenant je sais (et je sais quoi faire à la place). À votre santé! –

0

Je crois que vous êtes à la recherche:

.Add(Expression.IsNotEmpty("PropertyName")); 

et

.Add(Expression.IsNotNull("PropertyName")); 
+1

En fait ce n'est pas ce que je cherche. IsNotEmpty() s'applique uniquement aux collections (sacs, ensembles, etc.)! Si j'ai tort, s'il vous plaît faites le moi savoir. Je voudrais vérifier la valeur de "Msg" pour chaque entité individuelle et retourner uniquement ceux qui ont une valeur. L'équivalent de if (! String.IsNullOrEmpty (pvMsg)) {...} – alan

+0

Expression.IsNotEmpty() est identique à! String.IsNullOrEmpty(). – hackerhasid

+0

Notez que j'utilise la classe EXPRESSION, pas la classe RESTRICTIONS (comme vous l'avez fait dans le post) – hackerhasid

0

Voici ma carte et la définition de classe:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="Domain" namespace="Assembly.Domain"> 
    <class name="Assembly.Domain.FunctionCall, Domain" lazy="false" table="FunctionCallLog"> 

    <id name="LogId" column="LogId"> 
     <generator class="native" /> 
    </id> 

    <property name="LogTime" column="LogTime" /> 
    <property name="Username" column="Username" /> 
    <property name="CallerIp" column="CallerIp" /> 
    <property name="FunctionName" column="FunctionName" /> 
    <property name="Parameters" column="Parameters" /> 
    <property name="Msg" column="Msg" /> 
    <property name="FileName" column="FileName" /> 
    <property name="TimeSpan" column="TimeSpan" /> 

    </class> 
</hibernate-mapping> 


using System; 

namespace Assembly.Domain 
{ 
    public class FunctionCall 
    { 
     public int LogId { get; set; } 
     public DateTime LogTime { get; set; } 
     public string Username { get; set; } 
     public string CallerIp { get; set; } 
     public string FunctionName { get; set; } 
     public string Parameters { get; set; } 
     public string Msg { get; set; } 
     public string FileName { get; set; } 
     public int TimeSpan { get; set; } 
    } 
} 
0

Essayez ceci:

ICriteria lvCriteria = NHibernateHelper.GetCurrentSession() 
             .CreateCriteria(typeof(FunctionCall)) 
             .SetMaxResults(100) 
             .AddOrder(Order.Desc("LogId")); 

if (pvMsg.HasValue) 
{     
     lvCriteria.Add(Restrictions.IsNotNull("Msg")) 
       .Add(Restrictions.Not(Restrictions.Eq("Msg", "")); 
} 

Il peut y avoir une façon plus compacte d'exprimer cela.

+0

J'ai essayé ça aussi, ça ne marche pas comme prévu. Je suppose que je devrais préciser que peut-être IsNotEmpty() ne fonctionne pas parce que j'ai besoin d'appliquer ce filtre lorsque la collection est remplie; C'est pour éviter un timeout car cette table contient 1.000.000+ enregistrements. – alan

+0

Que voulez-vous dire par "Je dois appliquer ce filtre au fur et à mesure que la collection est peuplée"? Si la requête expire, vous devez saisir le code SQL émis par NH et l'exécuter directement, puis inspecter le plan d'exécution de la requête. –

+0

Il expire en raison de la quantité de données qui reviennent; il utilise des quantités impies de mémoire de serveur. Est-ce qu'il n'est pas possible de dire "seulement saisir les entités dont la propriété Msg contient une valeur" plutôt que "saisir tous les Msgs puis retourner uniquement ceux dont la propriété Msg a une valeur"? I.E. seulement ramasser les bonnes pommes de l'arbre plutôt que de cueillir toutes les pommes et de jeter les mauvaises pommes? – alan

Questions connexes