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如何连接远程db2数据库

如何通过 vb.net 让其他应用程序(计算器)在 winforms 中脱颖而出?

如何在 winform vb.net 上嵌入 Autodesk Viewer

如何在 IconButton VB .NET WinForm 中处理 MouseHover 和 MouseLeave 事件