Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linq to entities doesn't recognize a method

I have those methods:

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

When using:

count(some_guid, x => x.IsMatch(entityId, inviterId, routeId, luggageTypeId));

I get the following exception:

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.

What is the reason for this?
How can I solve it?

like image 300
Naor Avatar asked May 01 '11 02:05

Naor


People also ask

Which method is valid in LINQ?

The LINQ join methods are supported in LINQ to Entities, with the exception of those that accept an IEqualityComparer because the comparer cannot be translated to the data source. For more information, see Standard Query Operators in LINQ to Entities Queries.

Which join is not supported in LINQ?

Right outer join in LINQ A right outer join is not possible with LINQ. LINQ only supports left outer joins.

Is LINQ multithreaded?

By default, only one thread is used to execute a LINQ query. Parallel LINQ (PLINQ) is an easy way to enable multiple threads to execute a query. To see it in action, we will start with some code that only uses a single thread to double 200 million integers.

Is LINQ extension method?

All LINQ methods are extension methods, defined in the System. Linq namespace.


1 Answers

When using linq-to-entities you cannot use arbitrary .NET methods in query. Each method used in the query must be translatable to SQL. It will not help you to return Expession<Func<entityType, bool>> because where condition must be evaluated for each record on the database server.

For EF your code means something like:

SELECT COUNT(*)
FROM ...
LEFT JOIN ...
WHERE IsMatch(....) 

Because EF validates function names passed to the query it will throw exception because it doesn't know IsMatch equivalent on SQL server.

The only possible functions which can be used in Linq-to-entities are:

  • Cannonical functions with predefined mapping to SQL equivalent
  • EdmFunctions

EdmFunctions are methods marked with EdmFunctionAttribute which maps .NET function to SQL counterpart. Those functions usually cannot be executed in common .NET code because they do nothing or throw exception. They are only function place holder for Linq-to-entities. Available EdmFunctions are:

  • Predefined EdmFunctions in System.Data.Objects.EntityFunctions
  • Predefined EdmFunctions for SQL Server (not compact) in System.Data.Objects.SqlClient.SqlFunctions
  • Custom mapped SQL functions - import wizard in Entity designer allows you import SQL functions (except table valued functions). You can after that write custom static .NET function and map it by EdmFunction attribute to the SQL function imported to designer.
  • Custom model defined functions - this is special function written manually in EDMX file (opened as XML). It is custom reusable part of Entity SQL.

I have already described how to create model defined function in another answer. Creating mapped SQL function is pretty similar. Instead of manually creating Function element in EDMX you will map EdmFunctionAttribute properties to imported SQL function.

like image 177
Ladislav Mrnka Avatar answered Oct 13 '22 20:10

Ladislav Mrnka