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.
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.
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.
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).
The IQueryable interface inherits the IEnumerable interface so that if it represents a query, the results of that query can be enumerated.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With