2015-11-24 24 views
7

Tôi có một DataGrid mà có một bộ sưu tập ràng buộc để nó qua một BindingSource:Entity Framework Refresh Data

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

Một trong những đơn vị trong lưới đang được chỉnh sửa (và lưu) trong một hình thức khác nhau và tôi sẽ muốn làm mới lưới trên biểu mẫu này, bây giờ tôi đã thử tải lại thực thể, tải lại toàn bộ bối cảnh cục bộ nhưng vì một lý do nào đó nó không đọc các thực thể con liên quan. Bây giờ khi tôi đóng toàn bộ hình thức và mở nó lên một lần nữa tất cả đang được đọc.

Để làm mới thực thể tôi đang sử dụng đoạn mã sau:

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

Nhưng điều đó sẽ không tải bất kỳ đơn vị liên quan được ràng buộc với Entity sản phẩm. Tôi đã thử lại để cập nhật BindingSource sau đó nhưng không may mắn.

+0

Sau khi tải lại, bạn có ràng buộc lại không? – MichaelMao

+0

Có, nhưng sau khi ReloadAsync thuộc tính vẫn không chứa bất kỳ thực thể liên quan mới nào liên quan, chỉ có các thực thể cũ. Tôi đã thực hiện một giải pháp thay thế bằng cách tải thủ công các thực thể liên quan và gán chúng dưới dạng Danh sách <>. – Martin

+0

cố gắng sử dụng 'dbProducts.DataBind()' sau khi cập nhật –

Trả lời

2

tôi tình cờ được làm việc trên một "khách" cho một đồ thị đối tượng thực thể. Nhìn thấy câu hỏi của bạn tôi đã cho nó liên lạc cuối cùng để làm cho nó hữu ích trong trường hợp của bạn (và nhiều người khác). Nó không phải là khách truy cập thực sự như trong mẫu khách truy cập nổi tiếng, nhưng về cơ bản nó cũng giống nhau: nó đi qua một đồ thị đối tượng và thực hiện một số hành động cho mỗi thực thể mà nó gặp phải.

Sử dụng phương pháp này bạn chỉ có thể gọi ...

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

... và bạn sẽ thấy rằng product và tất cả các đối tượng tôn trọng được nạp lại.

Đây là mã:

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>(); 
    } 
} 

Nó là một hàm đệ quy bọc trong một phương pháp mở rộng. Tôi bọc phần đệ quy để tôi có thể gửi một địa phương HashSet xuống biểu đồ thu thập các thực thể được truy cập và do đó ngăn chặn các tham chiếu vòng tròn. Về cơ bản, hàm này áp dụng hành động được chỉ định cho thực thể, sau đó tìm các thuộc tính điều hướng của nó - có thể là các tham chiếu hoặc các bộ sưu tập - nhận giá trị của chúng (CurrentValue) và sau đó tự gọi các giá trị này.

Lưu ý rằng tôi cũng kiểm tra xem thuộc tính điều hướng có được tải hay không. Nếu không có điều này, một chuỗi tải lười biếng vô tận có thể được kích hoạt.

Cũng lưu ý rằng điều này sẽ kích hoạt một truy vấn cho từng thực thể trong biểu đồ. Đây không phải là một phương pháp thích hợp cho các đồ thị đối tượng lớn. Nếu bạn muốn làm mới một lượng lớn dữ liệu, bạn nên thực hiện một cách tiếp cận khác, tốt nhất là tạo một ngữ cảnh mới.

2

Bạn đã thử các ApplyCurrentValues ​​() chức năng, nó trông giống như bối cảnh của bạn cũng giống isin't lấy giá trị mới nhất, nếu bạn đã tạo ra một chức năng làm mới có quyền này:

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

Sau đó, bạn migth muốn áp dụng giá trị hiện tại trước khi thực hiện.

Xin lỗi nếu nó không giải quyết được vấn đề này, tôi đã gặp phải sự cố tương tự và giải quyết vấn đề này, có thể không phải là trường hợp của bạn.

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