linq to entities无法识别方法

时间:2011-05-01 02:25:35

标签: 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,
            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.

这是什么原因?
我该如何解决?

4 个答案:

答案 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是标有EdmFunctionAttribute的方法,它将.NET函数映射到SQL对应项。这些函数通常不能在常见的.NET代码中执行,因为它们什么都不做或抛出异常。它们只是Linq-to-entities的功能占位符。可用的EdmFunction是:

  • System.Data.Objects.EntityFunctions
  • 中预定义的EdmFunctions
  • System.Data.Objects.SqlClient.SqlFunctions
  • 中SQL Server(非紧凑型)的预定义EdmFunctions
  • 自定义映射SQL函数 - 实体设计器中的导入向导允许您导入SQL函数(表值函数除外)。您可以在此之后编写自定义静态.NET函数并将其按EdmFunction属性映射到导入设计器的SQL函数。
  • 自定义模型定义的函数 - 这是在EDMX文件中手动编写的特殊函数(以XML格式打开)。它是Entity 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,有一种更简单,更普通的方法,只需要很少的步骤即可完成。

  1. 使方法IsMatch成为静态。
  2. 直接从Expression<{your entity here}, bool>返回IsMatch
  3. 将其传递给:({your entity here}.IsMatch({parameters}))
  4. 休息可以和现在一样保持不变。

    编辑:示例 这将适用于特定实体,因此我将假设您的实体是订单。替换你自己的实体。

    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));