Как вернуть 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;
}