Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webforms data binding with EF Code-First Linq query error

In this example here, Scott shows doing a Linq query against the dbContext and binding the result directly to a GridView to show a list of products. His example is using the CTP4 version of the Code First stuff.

However, when I try do do the same thing using the latest version of EntityFramework 4.1, I get the following error:

Data binding directly to a store query (DbSet, DbQuery, DbSqlQuery) is not supported. Instead populate a DbSet with data, for example by calling Load on the DbSet, and then bind to local data.

I see that the DBQuery object is throwing this error on purpose in its implementation of IListSource.GetList(), which is used in databinding.

Any ideas why his example works? By the way, I know that I can make this work by putting in a projects.ToList(). My main question is whether something changed in the release version that makes this type of thing no longer work, or whether I'm missing something somewhere that can work around this error.

Just for reference, I'm referring to code like this:

MyDbContext db = new MyDbContext();

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

grdTest.DataSource = projects;
grdTest.DataBind();
like image 251
patmortech Avatar asked Jul 13 '11 05:07

patmortech


2 Answers

It is a long story, but I will try not to make it boring.

From the first version of EF we supported binding directly to queries. We earned enough experience about the pitfalls and confusion that this generated that we decided to explicitly disable it the new API we created for EF 4.1. The main issue for me was that WinForms and WPF data binding infrastructure assumes data sources are in memory and inexpensive to access. This has resulted in data binding often asking for the binding list more than once. On EF, binding to a reusable query necessarily implied wanting the latest results from the database, therefore we made it so that everytime the binding list is asked for we re-execute the query against the database. This caused at least two query executions everytime anyone bound to a query.

There were a few other aspects of binding to queries that were quite confusing or counterintuitive for many customers. I explore how things used to work in this blog post: http://blogs.msdn.com/b/diego/archive/2008/10/09/quick-tips-for-entity-framework-databinding.aspx

What you are supposed to do with DbContext API is to bind to local data directly and not to queries. For that we expose DbSet.Local which is an ObservableCollection that works pretty well for WPF and the ToBindingList method that wraps the collection in a BindingList for easier consumption in WinForms.

I can see that the exception message could be more explicit about the existence of the local property. I will consider filing a bug for that.

Hope this helps

like image 83
divega Avatar answered Oct 14 '22 07:10

divega


Came across the same issue and found this topic. ToList() worked:

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

    gridView.DataSource = products.ToList();
    gridView.DataBind();
}
like image 33
AFD Avatar answered Oct 14 '22 07:10

AFD