Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return an IQueryable from Linq to SQL query when the dbContext is with a 'using' block?

I've been coding with 'using' blocks but I am wondering if I can return an IQueryable from the following without the object being disposed before I access it.

public IQueryable<Contact> GetContacts(string clientID)
{
    using (dbDataContext db = new dbDataContext())
    {
        var contacts = from _contacts in db.Contacts
                        where _contacts.ClientID == clientID
                        orderby _contacts.LastName ascending
                        select _contacts;

        return contacts;
    }
}

Do I simply remove the 'using' block and let .Net manage the objects, or can I get Linq to run the query early and return the populated object.

like image 664
polom1nt Avatar asked Sep 15 '10 10:09

polom1nt


People also ask

What is the difference between returning IQueryable vs IEnumerable?

Both IEnumerable and IQueryable are forward collection. Querying data from a database, IEnumerable execute a select query on the server side, load data in-memory on a client-side and then filter data. Querying data from a database, IQueryable execute the select query on the server side with all filters.

What is IQueryable return?

IQueryable is executed. // // Returns: // A System.Type that represents the type of the element(s) that are returned when. // the expression tree associated with this object is executed.

Should I use IQueryable or IEnumerable?

IEnumerable: IEnumerable is best suitable for working with in-memory collection (or local queries). IEnumerable doesn't move between items, it is forward only collection. IQueryable: IQueryable best suits for remote data source, like a database or web service (or remote queries).

Does IEnumerable implement IQueryable?

The IQueryable interface inherits the IEnumerable interface so that if it represents a query, the results of that query can be enumerated.


1 Answers

If you don't expect to further compose the data (at the db-server), then:

return contacts.ToList().AsQueryable();

although in that case I'd prefer to return IEnumerable<Contact> or IList<Contact> to make the non-composable nature obvious. With the AsQueryable approach, it'll still be composable, but it'll compose via LINQ-to-Objects (so after it has fetched the records from the database).

If you do expect to further compose it, then you should pass the data-context (or, if possible, an upstream IQueryable<something>) into the method, and let the caller handle the lifetime:

public IQueryable<Contact> GetContacts(dbDataContext db, string clientID)
{
    return from _contacts in db.Contacts
           where _contacts.ClientID == clientID
           orderby _contacts.LastName ascending
           select _contacts;
}
like image 195
Marc Gravell Avatar answered Sep 22 '22 16:09

Marc Gravell