我不明白EF5 dbContext.Entry(entity).Reload()方法应该如何工作?

在这个例子中:

using System; using System.Collections.Generic; using dbModel; using System.Linq; using System.Data.Entity.Infrastructure; namespace WinApp { public partial class Form1 : Form { private dbEntities dbc; public IQueryable art; public IQueryable grp; public Form1() { InitializeComponent(); dbc = new dbEntities(); } private void GetData() { art = from a in dbc.ARTIKLIs select a; grp = from g in dbc.ART_GRUPE select g; artikliBindingSource.DataSource = art.ToList(); artGrupeBindingSource.DataSource = grp.ToList(); } private void Form1_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e) { dbc.SaveChanges(); } private void loadData_Click(object sender, EventArgs e) { this.GetData(); } private void refresh_Click(object sender, EventArgs e) { dbc.Entry(grp).Reload(); artGrupeBindingSource.ResetBindings(false); } } } 

一切都建立好。 但当我运行并单击刷新按钮时,我收到错误:

实体类型DbQuery`1不是当前上下文的模型的一部分

我只是尝试使用DbContext从存储为grp实体实例刷新数据。 我知道我可以将DbContext转换为ObjectContext然后使用Refresh方法,但是应该可以使用DbContext.Entry(entity).Reload();

有人可以在上面的代码中解释我的错误吗?

如果dbEntitiesDbContext ,那么你正在谈论有效的dbc.Entry().Reload(); ,放弃所有更改并重新加载实体,而不是重新加载查询。 但是,这不存在。 您可以使用dbc.Entry(myEntity).Reload() ( “MSDN – DbEntityEntry .Reload方法” )放弃对单个实体所做的任何更改。

DbContext并不意味着长寿,你打算用它来查询,然后摆脱它。 如果要将其强制转换为对象上下文,可以尝试:

 var ctx = ((IObjectContextAdapter)db).ObjectContext; ctx.Refresh(); 

这可能不是您所需要的。 它也不会从您的上下文中删除从db中删除的实体,并且它并不总是刷新关系。 你可能最好摆脱上下文并再次加载它:

 private void GetData() { // you could wrap this in a using statement, though that isn't necessary using (var dbc = new dbEntities()) { art = from a in dbc.ARTIKLIs select a; grp = from g in dbc.ART_GRUPE select g; artikliBindingSource.DataSource = art.ToList(); artGrupeBindingSource.DataSource = grp.ToList(); } } private void refresh_Click(object sender, EventArgs e) { GetData(); // not sure you need this next line now, but you should test artGrupeBindingSource.ResetBindings(false); } 

这可能会导致您的问题是您正在对ARTIKLIs进行更改并尝试跟踪它们。 为此,您可以使用以下内容保存更改,并且每次都不要重新加载ARTIKLIs

 private void GetData(bool loadArtikli = true) { // you could wrap this in a using statement, though that isn't necessary using (var dbc = new dbEntities()) { if (loadArtikli) { art = from a in dbc.ARTIKLIs select a; } grp = from g in dbc.ART_GRUPE select g; artikliBindingSource.DataSource = art.ToList(); artGrupeBindingSource.DataSource = grp.ToList(); } } private void refresh_Click(object sender, EventArgs e) { GetData(false); } public static void UpdateARTIKLI(ARTIKLI item) { using (var dbc = new dbEntities()) { if (item.Id > 0) { // update existing ones var dbitem = context.ARTIKLI .Find(item.Id); context.Entry(dbItem) .CurrentValues .SetValues(item); } else { // deal with new ones context.ARTIKLI.Add(item); } context.SaveChanges(); } }