开发者

Webforms data binding with EF Code-First Linq query error

开发者 https://www.devze.com 2023-03-19 17:11 出处:网络
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 F

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 missi开发者_运维问答ng 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();


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


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();
}


In looking at the EF4 Feature CTP4 release dll in Reflector, I can see that its DBQuery object does not implement IListSource.GetList() and throw an exception as the EF 4.1 dll does. I guess somewhere along the line they had a reason to no longer allow binding directly to the query, even though it implements IEnumerable.

This does not answer WHY they made this change, but at least I can see that there is a reason it would work in the older version.

0

精彩评论

暂无评论...
验证码 换一张
取 消