【问题标题】:VB.NET How to "Refresh" data DbContext in winformVB.NET如何在winform中“刷新”数据DbContext
【发布时间】: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()。说得通? :) 太糟糕了,你没有回答
  • 应该没问题。我没有输入完整的答案,因为我觉得我没有足够的时间来使它尽可能全面和详细,但我很高兴我能够以任何方式帮助你。

标签: vb.net winforms entity-framework


【解决方案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 每次更新实体时都会重新创建上下文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 2013-01-28
  • 1970-01-01
  • 2020-02-06
  • 2018-05-21
相关资源
最近更新 更多