我有这些方法:
public int count(
Guid companyId, Expression<Func<T, bool>> isMatch)
{
var filters = new Expression<Func<T, bool>>[]{
x => x.PriceDefinition.CompanyId == companyId,
isMatch
};
return GetCount(filters);
}
public virtual int GetCount(
IEnumerable<Expression<Func<T, bool>>> filters)
{
IQueryable<T> _query = ObjectSet;
if (filters != null)
{
foreach (var filter in filters)
{
_query = _query.Where(filter);
}
}
return _query.Count();
}
使用时:
count(some_guid, x => x.IsMatch(entityId, inviterId, routeId, luggageTypeId));
我得到以下异常:
LINQ to Entities does not recognize the method 'Boolean IsMatch(System.Nullable`1[System.Int64], System.Nullable`1[System.Int64], System.Nullable`1[System.Int64], System.Nullable`1[System.Int64])' method, and this method cannot be translated into a store expression.
这是什么原因?
我该如何解决?
答案 0 :(得分:14)
使用linq-to-entities时,不能在查询中使用任意.NET方法。查询中使用的每个方法都必须可以转换为SQL。它不会帮助您返回Expession<Func<entityType, bool>>
,因为必须为数据库服务器上的每条记录评估条件。
对于EF,您的代码意味着:
SELECT COUNT(*)
FROM ...
LEFT JOIN ...
WHERE IsMatch(....)
因为EF验证传递给查询的函数名称,所以它会抛出异常,因为它不知道SQL服务器上的IsMatch等价物。
可以在Linq-to-entities中使用的唯一可能功能是:
EdmFunctions
EdmFunctions是标有EdmFunctionAttribute
的方法,它将.NET函数映射到SQL对应项。这些函数通常不能在常见的.NET代码中执行,因为它们什么都不做或抛出异常。它们只是Linq-to-entities的功能占位符。可用的EdmFunction是:
System.Data.Objects.EntityFunctions
System.Data.Objects.SqlClient.SqlFunctions
EdmFunction
属性映射到导入设计器的SQL函数。我已经在另一个答案中描述了how to create model defined function。创建映射的SQL function is pretty similar。您可以将Function
属性映射到导入的SQL函数,而不是在EDMX中手动创建EdmFunctionAttribute
元素。
答案 1 :(得分:2)
您正在传递一个调用名为IsMatch
的函数的表达式。
LINQ to Entities不知道如何使用此功能。
答案 2 :(得分:1)
我正在处理类似的问题。在尝试使用我的自定义方法之前,工作解决方案正在使用.AsEnumerable()
。你可以take a look at it here。
答案 3 :(得分:0)
Actualy,你传递给count的东西看起来像这个函数:
bool anonymous_delagate#123(T entity)
{
return entity.IsMatch(a,b,c,d)
}
但是,这需要EF知道,在这个实体上调用的真正方法IsMatch
意味着什么。
我现在只能考虑推荐的是使用某种动态表达式伪造来动态创建这个查询。或者将您的设计重新设计为不同的设计。
Actualy,有一种更简单,更普通的方法,只需要很少的步骤即可完成。
IsMatch
成为静态。Expression<{your entity here}, bool>
返回IsMatch
。({your entity here}.IsMatch({parameters}))
休息可以和现在一样保持不变。
编辑:示例 这将适用于特定实体,因此我将假设您的实体是订单。替换你自己的实体。
public static Expression<Func<Order, bool>> IsMatch(int id, ...) // static method, that returns filtering expression
{
return i => i.Id == id; // create the filtering criteria
}
然后称之为:
count(some_guid, Order.IsMatch(entityId, inviterId, routeId, luggageTypeId));