Reputation: 89
I'm working on my own DeferredFirstOrDefault()
implementation. I want it to get an IQueryable
and append FirstOrDefault()
method to its expression tree.
Using the new Expression
i want to create a new IQueryable
which will have a call to FirstOrDefault()
in its expression tree.
Then i want to use that new IQueryable
to get the String SQL Query containing SELECT top(1) ... in it.
I have tried the following code:
IQueryable<T> query = queryable;
if (predicate != null)
query = queryable.Where(predicate);
var method_call_expression = Expression.Call(typeof(Queryable), "FirstOrDefault", new Type[] { typeof(T) }, query.Expression);
IQueryable<T> newQuery = query.Provider.CreateQuery<T>(method_call_expression);
var string_query = newQuery.ToQueryString();
Everything works fine, but as soon as it comes on .ToQueryString()
, throws an error:
System.ArgumentException: 'Expression of type 'HNLeye.Modules.Hierarchy.CompanyInfo' cannot be used for return type 'System.Collections.IEnumerable''
If you want reference, Entity Framework Plus
is aleady doing that. It provides DeferredFirstOrDefault()
method and then we do FutureValue()
on the returned DeferredQuery
. Just wanted same thing to be implemented by myself.
This way query is not materialized instantly, but when a round trip is required, all queries in batch are executed in a single SQL Query, which returns multiple result sets
, to be incremented using ADO.NET
.
Thanks in advance
Upvotes: 0
Views: 140
Reputation: 89
As stated by '@Svyatoslav Danyliv', using Take()
is the way to go instead of FirstOrDefault()
Upvotes: 0