Shahzaib Hassan
Shahzaib Hassan

Reputation: 89

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

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

Answers (1)

Shahzaib Hassan
Shahzaib Hassan

Reputation: 89

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

Upvotes: 0

Related Questions