Привязка данных Webforms с ошибкой запроса EF Code-First Linq - PullRequest
10 голосов
/ 13 июля 2011

В этом примере здесь Скотт показывает выполнение запроса Linq для dbContext и привязку результата непосредственно к GridView, чтобы показать список продуктов.В его примере используется CTP4-версия Code First.

Однако, когда я пытаюсь сделать то же самое, используя последнюю версию EntityFramework 4.1, я получаю следующую ошибку:

Привязка данных напрямую к запросу магазина (DbSet, DbQuery, DbSqlQuery) не поддерживается.Вместо этого заполните DbSet данными, например, вызвав Load на DbSet, а затем связывайтесь с локальными данными.

Я вижу, что объект DBQuery специально генерирует эту ошибку при реализации IListSource.GetList (), который используется в привязке данных.

Есть идеи, почему работает его пример?Кстати, я знаю, что могу сделать эту работу, вставив projects.ToList().Мой главный вопрос заключается в том, изменилось ли что-то в версии выпуска, из-за чего этот тип больше не работает, или мне не хватает чего-то, что может обойти эту ошибку.

Просто для справки, я имею в видукодировать так:

MyDbContext db = new MyDbContext();

var projects = from p in db.Projects
               where p.AnotherField == 2
               select p;

grdTest.DataSource = projects;
grdTest.DataBind();

Ответы [ 3 ]

14 голосов
/ 17 декабря 2012

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

В первой версии EF мы поддерживали привязку непосредственно к запросам. Мы накопили достаточно опыта о подводных камнях и путанице, которую это породило, и решили явно отключить его в новом API, который мы создали для EF 4.1. Основная проблема для меня заключалась в том, что инфраструктура привязки данных WinForms и WPF предполагает, что источники данных находятся в памяти и являются недорогими для доступа. Это привело к привязке данных, часто запрашивая список привязок более одного раза. В EF привязка к повторно используемому запросу обязательно подразумевала получение последних результатов из базы данных, поэтому мы сделали так, чтобы каждый раз, когда запрашивался список привязок, мы повторно выполняли запрос к базе данных. Это вызывало как минимум два выполнения запроса каждый раз, когда кто-либо был связан с запросом.

Было несколько других аспектов привязки к запросам, которые были довольно запутанными или нелогичными для многих клиентов. Я исследую, как все работало в этом сообщении в блоге: http://blogs.msdn.com/b/diego/archive/2008/10/09/quick-tips-for-entity-framework-databinding.aspx

То, что вы должны делать с DbContext API, это напрямую связываться с локальными данными, а не с запросами. Для этого мы раскрываем DbSet.Local, который представляет собой ObservableCollection, который очень хорошо работает для WPF, и метод ToBindingList, который упаковывает коллекцию в BindingList для более легкого потребления в WinForms.

Я вижу, что сообщение об исключении может быть более явным в отношении существования локального свойства. Я рассмотрю вопрос об ошибке для этого.

Надеюсь, это поможет

9 голосов
/ 15 ноября 2011

Наткнулся на ту же проблему и нашел эту тему. ToList () работает:

using (NorthwindContext context = new NorthwindContext())
{
    var products = from p in context.Products
                   where p.Discontinued == false
                   select p;

    gridView.DataSource = products.ToList();
    gridView.DataBind();
}
3 голосов
/ 13 июля 2011

Рассматривая dll-релиз ETP4 Feature CTP4 в Reflector, я вижу, что его объект DBQuery не реализует IListSource.GetList() и выдает исключение, как это делает dll EF 4.1.Я предполагаю, что где-то вдоль линии у них была причина больше не разрешать привязку непосредственно к запросу, даже если он реализует IEnumerable.

Это не отвечает, ПОЧЕМУ они внесли это изменение, но, по крайней мере, я вижу, что тамэто причина, по которой он будет работать в более старой версии.

...