Ole Albers
Ole Albers

Reputation: 9305

How to avoid converting iQueryable to a List?

I have the following (working) code:

 List<Location> allLocations = new List<Location>();
 using (MyContext context = new MyContext())
 {
     Login currentLogin = GetCurrentLogin(context);
     if (currentLogin != null)
     {
         foreach (var customer in currentLogin.Customers)
         {
             allLocations.AddRange(customer.Locations);
         }
     }
 }
 return allLocations.AsQueryable();

MyContext and its objects live within the entity framework. Customers and Locations are ICollection<>-Properties

This code works as expected, returning all locations from the users' Customers

But as you can see, I add the entity customer.Locations to a List.

At the end of that function I return that generated list as IQueryAble to be able to continue using LinQ-Expressions on the result.

Because of performance reasons I would like to skip the List<>-Step and stay inside IQueryAble

Is it possible?

Upvotes: 1

Views: 225

Answers (3)

user1666620
user1666620

Reputation: 4808

I'd be careful about using an IQueryAble or IEnumerable after having disposed the MyContext() as they are lazy loaded.

The query won't actually be evaluated until it is used in whichever function called it, but by then the context will have been disposed and an exception will be thrown.

Hence probably why the method originally populated the returned results into a List as it forced the query to be evaluated while the context was still active.

Upvotes: 1

CodeCaster
CodeCaster

Reputation: 151720

Change List<Location> allLocations to IQueryable<Location> allLocations.

Then you can do something like allLocations = currentLogin.Customers.SelectMany(c => c.Locations).AsQueryable().

Upvotes: 1

DavidG
DavidG

Reputation: 119156

How about doing the whole thing without a foreach loop by using SelectMany? That way you can keep everything as an IEnumerable:

using (MyContext context = new MyContext())
{
    Login currentLogin = GetCurrentLogin(context);
    if (currentLogin != null)
    {
        return currentLogin.Customers.SelectMany(c => c.Locations);
    }
}

Upvotes: 2

Related Questions