2013-08-11 14 views
18

ich alle Elemente meiner DbContext ohne es neu aktualisieren möchten, habe ich versucht, die folgenden und keiner von ihnen Sinn machen:Wie zu Aktualisieren DbContext

var context = ((IObjectContextAdapter)myDbContext).ObjectContext; 

var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(
            EntityState.Added 
            | EntityState.Deleted 
            | EntityState.Modified 
            | EntityState.Unchanged) 
          where entry.EntityKey != null 
          select entry.Entity); 

context.Refresh(RefreshMode.StoreWins, refreshableObjects); 
//....................................................................... 
foreach (var entry in this.Orm.ChangeTracker.Entries()) 
{ 
    entry.State = EntityState.Unchanged; 
} 
this.Orm.ChangeTracker.DetectChanges(); 

Und das einzige, das erfrischt meine DbContext:

foreach (var i in this.Orm.ChangeTracker.Entries()) 
    i.Reload(); 

Aber es ist zu langsam. Kannst du mir helfen, den richtigen Weg zu wählen?

+1

Haben Sie versucht, context.Refresh (Refreshmode, Entity) und im Debugger und SQL-Monitor sehen, ob es wirklich aktualisiert wird? – yonexbat

+0

@yonexbat: Ich habe die Daten in sql manuell geändert und 'context.Refresh (RefreshMode, Entity)' aufgerufen, aber keine der Änderungen aktualisiert, und das gleiche Szenario mit 'i.Reload();' durchgeführt und alle Änderungen in my aktualisiert 'DbContext'. – Mohsen

Antwort

29

Ich habe gerade gefunden, dass das Enumerable Ergebnis ausgewertet werden sollte, weil die Refresh Methode es als Objekt erhält und es nicht auswertet.

var context = ((IObjectContextAdapter)myDbContext).ObjectContext; 
var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(
              EntityState.Added 
              | EntityState.Deleted 
              | EntityState.Modified 
              | EntityState.Unchanged) 
          where entry.EntityKey != null 
          select entry.Entity).ToList(); 

context.Refresh(RefreshMode.StoreWins, refreshableObjects); 

Und ich ziehe folgendes:

var refreshableObjects = myDbContext.ChangeTracker.Entries().Select(c=>c.Entity).ToList(); 
context.Refresh(RefreshMode.StoreWins, refreshableObjects); 
+2

Mit Ihrer Methode habe ich: Das Element am Index 0 in der Sammlung von Objekten zu aktualisieren ist im addierten Zustand. Objekte in diesem Status können nicht aktualisiert werden. –

+2

@isti_spl: U'd besser Rollback vor References 'if (entry.State == EntityState.Added) entry.State = EntityState.Detached; // ...' – Mohsen

+0

entry.State ist readonly – HICURIN

9

Ich habe diese und id funktioniert:

//Search 
Box box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45); 

//breakpoint here, change Name of Box by sql management studio 

//Refresh 
var context = ((IObjectContextAdapter)dbContext).ObjectContext; 
context.Refresh(System.Data.Entity.Core.Objects.RefreshMode.StoreWins, box); 

//Check refresh and if it is in context 
box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45); 

Sind Sie sicher, dass es die gleiche db-Kontext?

+0

Entschuldigung, es als Antwort hinzuzufügen, aber ich weiß nicht, wie man Text im Kommentar formatiert. – yonexbat

+0

: Danke, ich benutze das, um eine einzelne Entity zu aktualisieren, aber ich muss alle Entitäten meines 'DbContext' aktualisieren, nicht nur eine einzelne 'Entity' oder' Entity Collection' oder' Related Entities einer Entity'. – Mohsen

+1

Ok. Ich würde den DbContext neu erstellen. myDbContext = neu MyDbContext(); – yonexbat

3
using System.Data.Entity.Core.Objects; 
using System.Data.Entity.Infrastructure; 
using System.Linq; 

namespace System.Data.Entity 
{ 
    public static class DbContextExtensions 
    { 
     /// <summary> 
     /// Refresh non-detached entities 
     /// </summary> 
     /// <param name="dbContext">context of the entities</param> 
     /// <param name="refreshMode">store or client wins</param> 
     /// <param name="entityType">when specified only entities of that type are refreshed. when null all non-detached entities are modified</param> 
     /// <returns></returns> 
     public static DbContext RefreshEntites(this DbContext dbContext, RefreshMode refreshMode, Type entityType) 
     { 
      //https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/ 
      var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; 
      var refreshableObjects = objectContext.ObjectStateManager 
       .GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged) 
       .Where(x => entityType == null || x.Entity.GetType() == entityType) 
       .Where(entry => entry.EntityKey != null) 
       .Select(e => e.Entity) 
       .ToArray(); 

      objectContext.Refresh(RefreshMode.StoreWins, refreshableObjects); 

      return dbContext; 
     } 

     public static DbContext RefreshAllEntites(this DbContext dbContext, RefreshMode refreshMode) 
     { 
      return RefreshEntites(dbContext: dbContext, refreshMode: refreshMode, entityType: null); //null entityType is a wild card 
     } 

     public static DbContext RefreshEntites<TEntity>(this DbContext dbContext, RefreshMode refreshMode) 
     { 
      return RefreshEntites(dbContext: dbContext, refreshMode: refreshMode, entityType: typeof(TEntity)); 
     } 
    } 
} 
2

In einigen Fällen, wenn eine Sammlung von einem Dritten App aktualisiert wurde, die Sammlung kann nicht geladen werden, wenn das Auffrischen Objekt der Sammlung.

hatte ich den Fall, in dem I mit einem ein bis viele relashionship auf ein Objekt B.

Anwendung 1 lädt ein Objekt A mit A.ListB leer ein Objekt A hatte. Anwendung 2 füllt die A.ListB-Auflistung. Anwendung 1 lädt das Objekt A neu.

Mit der obigen Lösung bleibt A.ListB leer. Ich musste die Sammlung A.ListB explizit neu laden.

Hier ist eine generische Art und Weise alle Sammlungen neu geladen zu haben:

var context = ((IObjectContextAdapter)this).ObjectContext; 

// detach all added entities 
ChangeTracker.Entries().Where(e => e.State == EntityState.Added).ToList().ForEach(e => e.State = EntityState.Detached); 

// select entities 
var refreshableObjects = ChangeTracker.Entries().Select(e => e.Entity).ToList(); 

// refresh each refreshable object 
foreach (var @object in refreshableObjects) 
{ 
    // refresh each collection of the object 
    context.ObjectStateManager.GetRelationshipManager(@object).GetAllRelatedEnds().Where(r => r.IsLoaded).ToList().ForEach(c => c.Load()); 

    // refresh the object 
    context.Refresh(RefreshMode.StoreWins, @object); 
}