2

I have an extension method as follows:

public static bool SatisfiesSomeCondition(this Post post, SomeObj someObj)
{
   return post.SomeObjId == someObj.SomeObjId;
}

And i'm trying to use it like this:

var query = ctx.Posts.Where(p => p.SatisfiesSomeCondition(someObj)).ToList();

But i get the error:

LINQ to Entities does not recognize the method 'Boolean SatisfiesSomeCondition(xx.xx.xx.Post, xx.xx.xx.SomeObj)' method, and this method cannot be translated into a store expression.

If i change the query to:

var query = ctx.Posts.Where(p => p.SomeObjId == someObj.SomeObjId).ToList();

Which is identical to the method.

It works fine, and executes the expected T-SQL.

Why doesn't my first query work? It's a static method, can't it figure out how to create the expression tree? (e.g a WHERE filter). Surely i don't have to materialize the query first? (which means the records i don't want come back over the wire, and i'm doing paging/ordering here, so that's not an option).

Of course, i can just go with what works (e.g the above), but the method SatisfiesSomeCondition is an existing method used across the domain and i want to re-use that functionality, not duplicate it.

Any ideas?

RPM1984
  • 72,246
  • 58
  • 225
  • 350

2 Answers2

4

Change it to:

public static IQueryable<Post> SatisfiesSomeCondition(this IQueryable<Post> query, SomeObj someObj)
{
   int id = someObj.SomeObjId;
   return query.Where(post => post.SomeObjId == id);
}

and use it like:

var query = ctx.Posts.SatisfiesSomeCondition(someObj)).ToList();

This way it should work. You can combine multiple Where conditions in single query so it should offer you at least basic reusablity.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
2

The LINQ to Entities engine has no way of knowing what your static method does.
LINQ queries can only be translated from expression trees.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Fair enough. What do you suggest? Duplicating functionality? Is there any way i can use that method without duping it? – RPM1984 Jan 31 '12 at 05:53
  • Unfortunately, not that I know of. You could make a function that returns an `Expression>`, but you won't be able to compose it. – SLaks Jan 31 '12 at 06:09
  • Yep, i was in the middle of trying to make the method return the predicate, but also my original query had an OR statement, which makes it difficult. e.g: `Where(x => x.Something || x.SatisfiesSomeCondition(someObj))`. So i would have to incorporate the entire `Where` condition into the method. Will look into predicatebuilder. – RPM1984 Jan 31 '12 at 09:10
  • Couldn't get it to work with PredicateBuilder either, same problem. Accepting this answer. For the record, i ended up duping the filtering logic. – RPM1984 Feb 01 '12 at 00:05