I am trying to implement an extension method that will work with linq2entities. I had initially assumed that if my extension method took and returned an IQueryable, and as long as my expression only made use of supported methods, then it would work fine. I was having alot of trouble, so as a last resort I copied an existing .NET extension method that I knew to work(FirstOrDefault) and simply renamed it. It would seem like it would evaluate the “cannot be translated into a store expression” validation based on the expression returned from the method, not the name of the method itself.
var prs = db.People.Where(p => p.PersonKey == 15).Select(p =>
new
{
id = p.PersonKey,
name1 = p.PersonHistories.AsQueryable().AsOf().Name
}
).ToList();
My extension method, which is just a copy of FirstOrDefault that I renamed:
public static TSource AsOf<TSource>(this IQueryable<TSource> source)
{
return source.Provider.Execute<TSource>(Expression.Call(null, ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { source.Expression }));
}
Error:
LINQ to Entities does not recognize the method
'Models.PersonHistory AsOf[PersonHistory](System.Linq.IQueryable`1[Models.PersonHistory])'
method, and this method cannot be translated into a store expression.
How do I implement an IQueryable extension method that is supported in Linq2Entities?
What I really want AsOf(source, DateTime asOf) to do is soemthing like source.FirstOrDefault<IHistory>(s => s.EndDate > asOf && asOf >= s.StartDate ), but I’m not sure how to accomplish this so that it is supported by linq2entities.
LINQKIT: This is what I’ve come up with using linqkit and I’m hoping somehow I can factor this into something more reusable:
Expression<Func<PersonHistory, bool>> IsCurrent = (p) => p.Ends > DateTime.Now && p.Starts <= DateTime.Now;
var query = db.PersonHistories.Where(IsCurrent);
- Have a more globally declared expression, instead of a local
variable. - Add a DateTime asOf parameter, instead of having .Now hard coded.
- And if possible, adapt it into an extension method(this sort of
is the same as #1, just that an extension method is ideal.
I saw you commented on my answer on another question, so i thought i’d reply here also. I’ve made some modifications and improvements to the code ( support for compiled queries and custom extension method to expression substitutions ).
This might serve as an answer:
Sorry for the brevity of my reply, it’s the middle of the night here and i’ve got to hurry as there is work to be done.
I’ll be happy to answer any questions you might have.