2010-02-21 10 views
1

J'utilise LINQ à NHibernate et j'ai rencontré un problème étrange en comparant les chaînes. code suivant fonctionne très bien, mais quand je Décommentez: //MyCompareFunc(dl.DamageNumber, damageNumberSearch) & & et commentaire: dl.DamageNumber.Contains (damageNumberSearch) & & il se décompose et semble que MyCompareFunc() retourne toujours vrai alors que dl.DamageNumber.Contains (damageNumberSearch) retourne parfois vrai et retourne parfois false. En d'autres termes, lorsque j'utilise string.Contains() dans une requête LINQ directement cela fonctionne, mais quand je le déplace vers une méthode, cela ne fonctionne pas.Problème étrange avec LINQ à NHibernate et comparaison de chaînes

internal List<DamageList> SearchDamageList(
    DateTime? sendDateFromSearch, DateTime? sendDateToSearch, string damageNumberSearch, 
    string insuranceContractSearch) 
    { 
     var q = from dl in session.Linq<DamageList>() 
       where 
       CommonHelper.IsDateBetween(dl.SendDate, sendDateFromSearch, sendDateToSearch) && 
       //MyCompareFunc(dl.DamageNumber, damageNumberSearch) && 
       dl.DamageNumber.Contains(damageNumberSearch) && 
       insuranceContractSearch == null ? true : CommonHelper.IsSame(dl.InsuranceContract, insuranceContractSearch) 
       select dl; 

     return q.ToList<DamageList>(); 
    } 

    private bool MyCompareFunc(string damageNumber, string damageNumberSearch) 
    { 
     return damageNumber.Contains(damageNumberSearch); 
    } 

Répondre

2

Je dois admettre que je ne suis pas un expert en NHibernate, mais en utilisant un autre ORM nous avons souvent courir dans le même genre de problème. Le fait est que le moteur LINQ, tout en traduisant la requête, est capable de reconnaître les fonctions de chaînes simples de la bibliothèque .NET comme Contains et de les traduire en équivalent SQL. Cet équivalent SQL fait la comparaison insensible à la casse (cela dépend des paramètres de la base de données, mais c'est généralement la valeur par défaut). D'autre part, il ne peut pas analyser le code source de votre fonction personnalisée et ne peut donc pas le traduire en SQL et doit simplement l'exécuter en mémoire après avoir préchargé le résultat de la requête précédente. la base de données. Cela signifie qu'il est exécuté en tant que code .NET, où la comparaison est effectuée par défaut sensible à la casse.

Cela pourrait être la raison de votre non-concordance des résultats;)

+0

Merci Thomas, mais dans mon cas particulier, la comparaison se fait sur les nombres. En effet mon utilisation de string.Contains dans "MyCompareFunc" est quelque chose comme: "1" .Contains ("12345") –

1

Linq fonctionne avec des expressions, et non avec des fonctions compliled. Ça ira si vous utilisez expression> au lieu de la méthode "compilée".