在此示例here中,Scott显示对dbContext执行Linq查询并将结果直接绑定到GridView以显示产品列表。他的例子是使用Code First的CTP4版本。
然而,当我尝试使用最新版本的EntityFramework 4.1做同样的事情时,我收到以下错误:
直接将数据绑定到商店查询(DbSet,DbQuery,DbSqlQuery) 不支持。而是使用数据填充DbSet,例如 在DbSet上调用Load,然后绑定到本地数据。
我看到DBQuery对象在IListSource.GetList()的实现中故意抛出此错误,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();
答案 0 :(得分:14)
这是一个很长的故事,但我会尽量不让它变得无聊。
从EF的第一个版本开始,我们支持直接绑定到查询。我们获得了足够的经验,因为我们决定明确禁用它为我们为EF 4.1创建的新API。 对我来说,主要问题是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中使用。
我可以看到异常消息可以更明确地说明是否存在本地属性。我会考虑为此提交一个错误。
希望这有帮助
答案 1 :(得分:9)
遇到同样的问题,发现了这个话题。 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();
}
答案 2 :(得分:3)
在Reflector中查看EF4 Feature CTP4发行版dll,我可以看到它的DBQuery对象没有实现IListSource.GetList()
并抛出异常,就像EF 4.1 dll那样。我猜他们有一个理由不再允许直接绑定到查询,即使它实现了IEnumerable。
这并没有回答为什么他们做了这个改变,但至少我可以看到它在旧版本中有用的原因。