C# linq到实体不';我不认识一种方法
我有这些方法:C# linq到实体不';我不认识一种方法,c#,.net,entity-framework,linq-to-entities,C#,.net,Entity Framework,Linq To Entities,我有这些方法: public int count( Guid companyId, Expression<Func<T, bool>> isMatch) { var filters = new Expression<Func<T, bool>>[]{ x => x.PriceDefinition.CompanyId == companyId, isM
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();
}
我得到以下例外情况:
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.
原因是什么?如何解决此问题?您正在传递一个表达式,该表达式调用名为
IsMatch
的函数
LINQ to Entities不知道该如何处理此函数。我正在处理类似的问题。工作解决方案是在尝试使用我的自定义方法之前使用
.AsEnumerable()
。您可以。实际上,传递给count的内容类似于此函数:
bool anonymous_delagate#123(T entity)
{
return entity.IsMatch(a,b,c,d)
}
但是,这需要EF知道,在这个实体上调用的方法IsMatch
的真正含义
我现在唯一能想到的重新编译就是使用某种动态表达式伪造来动态创建这个查询。或者重新设计你的设计
实际上,有一种更简单、正常的方法,只需几步即可完成
IsMatch
静态IsMatch
返回Expression
({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
}
使用linq to实体时,不能在查询中使用任意.NET方法。查询中使用的每个方法都必须可翻译为SQL。返回
expression
对您没有帮助,因为必须为数据库服务器上的每条记录计算where条件
对于EF,您的代码意味着:
SELECT COUNT(*)
FROM ...
LEFT JOIN ...
WHERE IsMatch(....)
因为EF验证传递给查询的函数名,所以它将抛出异常,因为它不知道SQL server上的IsMatch等价物
Linq to实体中唯一可能使用的功能是:
- 使用预定义的SQL等效映射
EDM功能
EdmFunctionAttribute
标记的方法,它将.NET函数映射到SQL对应项。这些函数通常不能在公共.NET代码中执行,因为它们不执行任何操作或引发异常。它们是Linq to实体的唯一功能占位符。可用的功能包括:
System.Data.Objects.EntityFunctions中预定义的函数
System.Data.Objects.SqlClient.SqlFunctions
- 自定义映射SQL函数-实体设计器中的导入向导允许您导入SQL函数(表值函数除外)。之后,您可以编写自定义静态.NET函数,并通过
属性将其映射到导入设计器的SQL函数EdmFunction
- 自定义模型定义函数-这是在EDMX文件(以XML形式打开)中手动编写的特殊函数。它是实体SQL的自定义可重用部分
我已经在另一个答案中描述过。创建映射。不要在EDMX中手动创建
函数
元素,而是将EdmFunctionAttribute
属性映射到导入的SQL函数。@SLaks♦: 抱歉,我用isMatch委托更新了问题。LINQ to Entities不知道如何将isMatch
转换为SQL。您需要将其替换为表达式树。♦: “用表达式树替换它”是什么意思?添加一个numerable会将整个表加载到内存中,经过companyId的筛选后,我仍然有很多结果。@Naor:好吧,这对我来说很有效,因为我的工作结果很少。我不知道你的,你能举个例子吗?我没有;我不理解最后两个步骤。您编写的静态IsMatch方法是否必须返回不基于其他函数的委托?我可以使用例如“return I=>I.MyMethod(id);”吗?不可以。您必须使用eiter将其完全创建为表达式,或者像Ladislav所说的那样,将函数映射到存储过程。
count(some_guid, Order.IsMatch(entityId, inviterId, routeId, luggageTypeId));
SELECT COUNT(*)
FROM ...
LEFT JOIN ...
WHERE IsMatch(....)