2010-10-28 5 views
1

Il est connu que les génériques ne supportent pas la comparaison d'égalité si la restriction "class" n'est pas appliquée à un paramètre. Comment pouvons-nous contourner ce problème pour LINQ To Entities?Entity Framework compare générique

query.Where(p => p.CategoryId == categoryId); //doesn't work 

La solution que j'ai vu avant était d'utiliser EqualityComparer.Default.Equal, mais il ne peut pas être traduit en SQL.

J'ai aussi essayé de construire l'expression manuelle:

 var parameterExpression = Expression.Parameter(typeof(T)); 
     var categoryIdPropertyExpression = Expression.Property(parameterExpression, "CategoryId"); 
     var categoryIdExpression = Expression.Constant(categoryId); 
     var equalityExpression = Expression.Equal(categoryIdPropertyExpression, categoryIdExpression); 
     Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(equalityExpression, parameterExpression); 

     query = query.Where(lambda); 

Mon T peut être longue ou Nullable. Et ce code jette une exception si T est Nullable car il peut vérifier l'égalité de long et Nullable.

Y a-t-il des solutions de contournement qui fonctionnent pour EF?

Répondre

0

Cette requête fonctionne-t-elle lorsque vous utilisez un type Nullable?

query.Where(p => 
    (p.CategoryId == null && categoryId == null) 
    || (p.CategoryId.Value == categoryId.Value)); 

Votre requête d'origine plus ou moins produit l'instruction SQL suivante:

SELECT * 
FROM [Table] 
WHERE [CategoryId] = @p0 

Ma requête produit:

SELECT * 
FROM [Table] 
WHERE (([CategoryId] IS NULL) AND (@p0 IS NULL)) OR ([CategoryId] = @p0) 

La première requête ne retourne pas quand categoryId est null, mais le second fait.

Comme alternative (ce qui est moins lisible, mais fonctionne également), vous pouvez essayer ceci:

from p in query 
join a in new [] { categoryId } on p.CategoryId equals a 
select p; 

Vive.

1

La solution qui m'a aidé: passer ParameterID comme générique et changer la ligne

var categoryIdExpression = Expression.Constant(categoryId); 

à

var categoryIdExpression = Expression.Constant(categoryId, typeof(P));