Как вернуть IQueryable из Linq в SQL-запрос, когда dbContext имеет блок "using"?
Я кодировал с помощью блоков "using", но мне интересно, могу ли я вернуть IQueryable из следующего, не удаляя объект перед его доступом.
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;
}
}
Я просто удаляю блок "using" и позволяю .Net управлять объектами, или я могу заставить Linq запустить запрос раньше и вернуть заполненный объект.
4 ответов
если вы не ожидаете дальнейшего составления данных (на db-сервере), то:
return contacts.ToList().AsQueryable();
хотя в таком случае я бы предпочел вернуться IEnumerable<Contact>
или IList<Contact>
сделать non-composable природу очевидной. С AsQueryable
подходите, все равно быть composable, но он будет составлять через LINQ-to-Objects (so после он извлек записи из базы данных).
если вы do ожидайте дальнейшего его составления, затем вы должны пройти контекст данных (или, если возможно, восходящий IQueryable<something>
) на метод, и пусть вызывающий обрабатывает время жизни:
public IQueryable<Contact> GetContacts(dbDataContext db, string clientID)
{
return from _contacts in db.Contacts
where _contacts.ClientID == clientID
orderby _contacts.LastName ascending
select _contacts;
}
можете ли вы сделать объект контекста экземпляром-членом вашего класса? Если вы можете, вы отложите вызов для запуска запроса, пока не коснетесь перечислителя, лежащего в основе возвращаемого экземпляра IQueryable. Это зависит от того, что вы хотите сделать. Вам нужно вернуть IQueryable из этого метода или вы можете обойтись IEnumerable ?
экземпляр объекта contact в результирующем наборе IQueryable сохранит ссылку на datacontext, используемую в блоке using, и будет работать в клиентском коде так, как ожидалось. Вы сможете выполнять отложенные операции SQL на результирующем экземпляре IQueryable и выполнять другие операции IQueryable нормально.
вы могли бы сделать что-то подобное
public IQueryable<Contact> GetContacts(string clientID)
{
IQueryable contacts;
using (dbDataContext db = new dbDataContext())
{
contacts = from _contacts in db.Contacts
where _contacts.ClientID == clientID
orderby _contacts.LastName ascending
select _contacts;
}
return contacts;
}