实体框架刷新数据

我有一个数据网格,它有一个通过BindingSource绑定到它的集合:

            bsProducts.DataSource = cc.Products.Local.ToBindingList();

网格中的一个实体正在以不同的形式进行编辑(和保存),我想刷新此表单上的网格,现在我尝试重新加载实体,重新加载整个本地上下文,但由于某种原因它不是阅读相关的子实体。 现在,当我关闭整个表单并再次打开时,所有内容都正在读取。

刷新实体我使用下面的代码:

        await cc.Entry<Product>(product).ReloadAsync();

但是,这不会加载绑定到产品实体的任何相关实体。 之后我尝试更新BindingSource,但没有运气。


我碰巧正在为一个实体对象图的“访问者”工作。 看到你的问题,我给了它最后一个触摸,使其在你的情况下(和许多其他)有用。 它不像真正的知名访问者模式那样是一个真正的访问者,但它基本上是一样的:它遍历一个对象图并对它遇到的每个实体执行一些操作。

使用这种方法,你可以简单地调用...

cc.Visit(product, e => cc.Entry(e).Reload());

...你会看到product和所有粘附的对象都被重新加载。

代码如下:

public static class DbContextExtensions
{
    public static void Visit(this DbContext context, object entity, Action<object> action)
    {
        Action<object, DbContext, HashSet<object>, Action<object>> visitFunction = null; // Initialize first to enable recursive call.
        visitFunction = (ent, contxt, hashset, act) =>
          {
              if (ent != null && !hashset.Contains(ent))
              {
                  hashset.Add(ent);
                  act(ent);
                  var entry = contxt.Entry(ent);
                  if (entry != null)
                  {
                      foreach (var np in contxt.GetNavigationProperies(ent.GetType()))
                      {
                          if (np.ToEndMember.RelationshipMultiplicity < RelationshipMultiplicity.Many)
                          {
                              var reference = entry.Reference(np.Name);
                              if (reference.IsLoaded)
                              {
                                  visitFunction(reference.CurrentValue, contxt, hashset, action);
                              }
                          }
                          else
                          {
                              var collection = entry.Collection(np.Name);
                              if (collection.IsLoaded)
                              {
                                  var sequence = collection.CurrentValue as IEnumerable;
                                  if (sequence != null)
                                  {
                                      foreach (var child in sequence)
                                      {
                                          visitFunction(child, contxt, hashset, action);
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
          };
        visitFunction(entity, context, new HashSet<object>(), action);
    }

    // Get navigation properties of an entity type.
    public static IEnumerable<NavigationProperty> GetNavigationProperies(this DbContext context, Type type)
    {
        var oc = ((IObjectContextAdapter)context).ObjectContext;
        var objectType = ObjectContext.GetObjectType(type); // Works with proxies and original types.

        var entityType = oc.MetadataWorkspace.GetItems(DataSpace.OSpace).OfType<EntityType>()
                           .FirstOrDefault(et => et.Name == objectType .Name);
        return entityType != null
            ? entityType.NavigationProperties
            : Enumerable.Empty<NavigationProperty>();
    }
}

它是一个用扩展方法包装的递归函数。 我包装了递归部分,以便我可以向收集访问实体的图形发送本地HashSet ,从而防止循环引用。 基本上,该函数将指定的操作应用于实体,然后查找其导航属性(可以是引用或集合),获取它们的值( CurrentValue ),然后调用它们以获取这些值。

请注意,我还检查导航属性是否已加载。 没有这个,懒惰的加载链可能会被触发。

另请注意,这会触发图中每个实体的一个查询。 这不适用于大型对象图。 如果你想刷新大量的数据,你应该采取不同的方法,最好创建一个新的上下文。


您是否尝试过ApplyCurrentValues()函数,如果您已经创建了一个刷新函数,它看起来就像您的上下文不会采用最新值:

 bsProducts.DataSource = cc.Products.Local.ToBindingList();
 bsProducts.DataBind();

那么你在迁徙之前想要应用当前值。

对不起,如果它没有解决它,我有一个类似的问题,并与此解决,可能不是你的情况。

https://msdn.microsoft.com/en-us/library/dd487246(v=vs.110).aspx

链接地址: http://www.djcxy.com/p/88949.html

上一篇: Entity Framework Refresh Data

下一篇: cannot mount volume over existing file, file exists