众所周知,如果“class”限制未应用于参数,则泛型不支持相等性。我们如何为LINQ To Entities解决它?
query.Where(p => p.CategoryId == categoryId); //doesn't work
我之前看到的解决方法是使用EqualityComparer.Default.Equal,但它无法转换为SQL。
我还尝试手动构建表达式:
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);
我的T可能很长或可以为空。如果T为Nullable,则此代码抛出异常,因为它可以检查long和Nullable的等式。
是否有适用于EF的变通办法。
答案 0 :(得分:1)
帮助我的解决方案:将ParameterId作为通用传递并更改行
var categoryIdExpression = Expression.Constant(categoryId);
到
var categoryIdExpression = Expression.Constant(categoryId, typeof(P));
答案 1 :(得分:0)
当您使用可空类型时,此查询是否有效?
query.Where(p =>
(p.CategoryId == null && categoryId == null)
|| (p.CategoryId.Value == categoryId.Value));
您的原始查询或多或少会产生以下SQL:
SELECT *
FROM [Table]
WHERE [CategoryId] = @p0
我的查询产生:
SELECT *
FROM [Table]
WHERE (([CategoryId] IS NULL) AND (@p0 IS NULL)) OR ([CategoryId] = @p0)
当categoryId
为null
时,第一个查询不会返回结果,但第二个查询不会返回结果。
作为替代方案(可读性较差,但也有效),你可以试试这个:
from p in query
join a in new [] { categoryId } on p.CategoryId equals a
select p;
干杯。