Привязка GridView к IQueryable <T> - PullRequest
       37

Привязка GridView к IQueryable <T>

5 голосов
/ 04 марта 2011

Этот вопрос чисто академический, потому что я никогда не мечтал сделать это в реальном коде.

Используя LINQ to SQL, я хочу связать IQueryable<T> с GridView. Я попытался сделать это с помощью следующего кода, но я получил исключение:

Невозможно получить доступ к удаленному объекту. Имя объекта: 'DataContext, доступ к которому осуществляется после удаления.'.

Вот мой код, который получает IQueryable<tabGenre> с использованием LINQ to SQL:

public static IQueryable<lu_Genre> GetGenres2() {
    using (BooksContextDataContext ctx = new BooksContextDataContext()) {
        IQueryable<tabGenre> iq = from g in ctx.tabGenre
                                  select g;
        return iq;
    }
}

А вот мой код, который привязывает GridView к возвращенному IQueryable<T>.

private void GetGenres() {
    gvGenre.DataSource = Genre.GetGenres2();
    gvGenre.DataBind();
}

Так почему это не работает? Я мог бы просто .ToList<tabGenre>(), вернуть его, привязать к нему, и тогда он будет работать, но почему IQueryable не работает таким же образом? Здесь я действительно пытаюсь достичь понимания того, что может сделать IQueryable.

EDIT: Я также пытался отключить отложенную загрузку, но безрезультатно.

Ответы [ 3 ]

16 голосов
/ 04 марта 2011

Вы можете думать о IQueryable как о инструкциях, необходимых для выполнения запроса. Когда вы вызываете .ToList (), вы выполняете IQueryable () для возврата фактических данных. Когда вы связываетесь с IQueryable (), он будет ожидать наличия источника данных для получения фактических данных при каждом вызове DataBind ().

Когда вы устанавливаете gvGenre.DataSource () = Genre.GetGenres2 (), DataContext, необходимый для получения фактических данных на основе вашего IQueryable, уничтожается до того, как произойдет вызов DataBind ().

Это работает, если вы вызываете .ToList (), потому что вы физически выходите и получаете данные, а затем помещаете их в память.

Хранение IQueryable похоже на хранение только запроса. Вы не можете выполнить запрос, если источник данных, с которым он рассчитывает работать, не существует.

2 голосов
/ 04 марта 2011

Единственный эффект от использования этого блока - ограничение продолжительности жизни ctx для самого блока.

Срок полезного использования iq зависит от срока службы ctx.Вы явно утилизируете ctx до использования iq.

Способ устранения проблемы - избавиться от используемого блока или заставить iq выполнить оценку внутри блока (например, iq = iq.ToList()) и вернуть только результаты этой оценки.Если вы не заинтересованы в последнем, просто откажитесь от использования.ctx будет утилизирован в какой-то момент, когда это никому не нужно.Может быть, не идеально, но это жизнь с сборщиком мусора.Вы уверены, что это создаст проблему, если она останется?Не чините то, что еще не сломано.

0 голосов
/ 26 сентября 2012
    public IQueryable MembershipGetAll()
    {


            var obj = (from mem in db.GetTable<MEMBERSHIP>()
                           select new
                           {
                               NAME = mem.MEMBERSHIP.NAME,
                               TYPE = mem.MEMBERSHIP.TYPE,
                               TAX_ID = mem.TAX_RATE.TAX_ID,
                               DISCOUNT = mem.DISCOUNT,
                               DISCOUNT_PERCENT = mem.DISCOUNT_PERCENT,

                           }
                          ).AsQueryable();
            return obj;

    }


private void LoadMembership()
{
    IQueryable mem = null;
    mem = eb.MembershipGetAll();
    grdMembership.DataSource = mem;
    grdMembershipRates.DataBind();
}

Просто сделай это так

...