VB.NET如何在winform中“刷新”数据DbContext
Posted
技术标签:
【中文标题】VB.NET如何在winform中“刷新”数据DbContext【英文标题】:VB.NET How to "Refresh" data DbContext in winform 【发布时间】:2018-02-26 18:30:12 【问题描述】:我有一个DataDridview
,里面装满了用我的DbContext
查询的对象。
我以这种形式展示了有关我的对象的一些基本信息。
每次在DataDridview
中选择不同的对象时,我都想从 BD 查询最新信息。我也希望能够修改这些对象。
我已经能够做到这一点。例如,要修改一个对象,我将执行以下步骤:
-创建一个新的DbContext
- 使用.Selectedrows(0).DatabountItem
从我的 Datagridview 获取对象
- 使用该对象的 ID,我将使用我的新 DbContext
查询数据库中的(最新)记录
- 将旧对象(修改后的)属性一一分配给新对象
-.SaveChanges
在我的新Dbcontext
上。
但是必须有更好的方法,对吗? :/
如果我理解正确,通过这种方式,我最终会得到大量未使用的 Dbcontext,我怀疑这是最佳实践。
但是,每当我 .Dispose
我的上下文时,所有 EF 导航属性都会被破坏,并且我会在整个地方弹出异常......所以在我看来,理想的解决方案只是刷新我将用于的唯一 DbContext 中的数据整个表格。但这有可能吗?
也许解决方案很明显,但我就是看不到。
如果我不清楚,请告诉我,我会尽力重新制定。
任何帮助将不胜感激,谢谢!
** 编辑 **
最后,这是最适合我的解决方案:
我确实为每个逻辑操作创建了一个新的 DbContext,然后立即 .Dispose
它...
除了当我在我的 datagridview 中显示有关特定行的信息时。
相反,我创建了一个新的上下文并保持打开状态。只有当datagridview.SelectionChanged
事件触发时,我才会.Dispose
。
不立即处理此上下文的原因是:如果用户保存了他的更改,但同时其他人也在同一记录上保存了更改,则(未同步的)上下文将遇到并发问题..我可以让用户知道它,而不是覆盖该行,这会很糟糕。
如果我需要其他地方的 EF 的这些导航属性,我可以简单地通过 .Include("MyOtherTable")
急切地加载我需要的一切。(因为当上下文被释放时导航属性停止工作)
【问题讨论】:
如果您为每个逻辑操作创建一个新的DbContext
,那么您就正确进行了操作。不要为整个应用程序创建单个上下文,这只会导致问题。听起来您遇到了“延迟加载”的问题。您需要确保您的查询在上下文的生命周期范围内完成。查看使用.Include
函数以确保加载所有依赖对象。
您的评论让我更好地理解了上下文。我会按照你在这里的解释做。至于编辑,只要没有保存更改或 datagridview.SelectedIndexChanged 没有触发,我就会让我的上下文存在。当任何一种情况发生时,我MyContext.Dispose()
。说得通? :) 太糟糕了,你没有回答
应该没问题。我没有输入完整的答案,因为我觉得我没有足够的时间来使它尽可能全面和详细,但我很高兴我能够以任何方式帮助你。
【参考方案1】:
在这种情况下,我只会使用一个上下文。您必须注意从其他线程访问上下文 - 它可能导致事务错误(“不允许新事务,因为会话中正在运行其他线程”)
如果您将 DataGridView 与 EF 上下文中的 DataSource 一起使用,您只需重新加载实体即可。 我在我的上下文中编写了扩展方法:
public partial class MyContext : testEntities1
public void Refresh(IEnumerable entities)
var ctx = ((IObjectContextAdapter)this).ObjectContext;
ctx.Refresh(System.Data.Entity.Core.Objects.RefreshMode.StoreWins, entities);
它比 entry.Reload(); 快得多
F.E.:
List<MyEntities> items = new List<MyEntities>();
foreach(DataGridViewRow row in dataGridView1.SelectedRows)
items.Add((MyEntities)row.DataBoundItem);
context.Refresh(items);
【讨论】:
我收到此错误:The element at index 0 in the collection of objects to refresh has a null EntityKey property value or is not attached to this ObjectStateManager.
我确保在加载时创建了一个 DbContext,并且再也不会重新分配它......
请粘贴用于在 DGV 中附加 DataSource 的代码
该错误是由(From imp In dbContext.Imprime.AsNoTracking Where imp.imp_num.Contains(numero) AndAlso imp.imp_titre.Contains(titre) Select imp).ToList()
中的.AsNoTracking
引起的,我在进行测试时忘记了它。所以,现在我的数据库和我的Datagridview 都是自动同步的。让我了解发生了什么,大声笑,我会将您的答案标记为已接受:)
在应用程序的整个生命周期中只使用一个 DbContext
实例是一种巨大的反模式,几乎所有有 EF 经验的人都会告诉您避免这种模式。
@BradleyUffner 我在这种情况下说,以前 OP 每次更新实体时都会重新创建上下文。以上是关于VB.NET如何在winform中“刷新”数据DbContext的主要内容,如果未能解决你的问题,请参考以下文章
选择新数据后如何在 VB.Net 中刷新 Datagridview
如何在 VB.Net winforms 应用程序中找到 main() 入口点?
如何通过 vb.net 让其他应用程序(计算器)在 winforms 中脱颖而出?
如何在 winform vb.net 上嵌入 Autodesk Viewer
如何在 IconButton VB .NET WinForm 中处理 MouseHover 和 MouseLeave 事件