简体   繁体   English

Webforms 数据绑定与 EF Code-First Linq 查询错误

[英]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.示例中,Scott 展示了对 dbContext 执行 Linq 查询并将结果直接绑定到 GridView 以显示产品列表。 His example is using the CTP4 version of the Code First stuff.他的例子是使用 Code First 的 CTP4 版本。

However, when I try do do the same thing using the latest version of EntityFramework 4.1, I get the following error:但是,当我尝试使用最新版本的 EntityFramework 4.1 做同样的事情时,我收到以下错误:

Data binding directly to a store query (DbSet, DbQuery, DbSqlQuery) is not supported.不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)。 Instead populate a DbSet with data, for example by calling Load on the DbSet, and then bind to local data.而是使用数据填充 DbSet,例如通过在 DbSet 上调用 Load,然后绑定到本地数据。

I see that the DBQuery object is throwing this error on purpose in its implementation of IListSource.GetList(), which is used in databinding.我看到 DBQuery object 在其用于数据绑定的 IListSource.GetList() 的实现中故意抛出此错误。

Any ideas why his example works?任何想法为什么他的例子有效? By the way, I know that I can make this work by putting in a projects.ToList() .顺便说一句,我知道我可以通过放入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();

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.从 EF 的第一个版本开始,我们支持直接绑定到查询。 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.我们获得了足够的经验来了解由此产生的陷阱和混乱,因此我们决定明确禁用我们为 EF 4.1 创建的新 API。 The main issue for me was that WinForms and WPF data binding infrastructure assumes data sources are in memory and inexpensive to access.对我来说主要问题是 WinForms 和 WPF 数据绑定基础设施假设数据源位于 memory 中并且访问成本低廉。 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.在 EF 上,绑定到可重用查询必然意味着需要来自数据库的最新结果,因此我们这样做是为了每次要求绑定列表时,我们都会对数据库重新执行查询。 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我在这篇博文中探讨了过去的工作方式: 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.你应该对 DbContext API 做的是直接绑定到本地数据而不是查询。 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.为此,我们公开了 DbSet.Local,它是一个 ObservableCollection,它非常适用于 WPF 和将集合包装在 BindingList 中以便在 WinForms 中使用的 ToBindingList 方法。

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

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.在 Reflector 中查看 EF4 Feature CTP4 版本 dll 时,我可以看到它的 DBQuery object 没有实现IListSource.GetList()并像 EF 4.1 Z06416233FE5EC4C593ZAB24AF13122E 那样抛出异常。 I guess somewhere along the line they had a reason to no longer allow binding directly to the query, even though it implements IEnumerable.我猜他们有理由不再允许直接绑定到查询,即使它实现了 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.这并不能回答他们为什么要进行此更改,但至少我可以看到它可以在旧版本中使用是有原因的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM