Implementation of DeferredFirstOrDefault to execute SQL queries in batch with multiple result sets

94 views Asked by At

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

1

There are 1 answers

0
Shahzaib Hassan On

As stated by '@Svyatoslav Danyliv', using Take() is the way to go instead of FirstOrDefault()