2016-04-15 14 views
7

Ich arbeite an einer C# ASP.NET MVC 5-Webanwendung mit EF 5. Mapping meiner Datenbanktabellen mit EF generiert eine DbContext Klasse und eine .edmx Datei. Heute las ich a great article about creating generic DAL classes, aber ich hielt auf dem folgenden Satz:Verwirrende Artikel und Dokumentation über die Unterschiede (falls vorhanden) zwischen System.Data.EntityState.Add & DbSet.Add

Beachten Sie, dass die Eingabemethode mit dem Zustand eines Unternehmens ändern nur die tatsächliche Einheit auswirken, die Sie in der Methode übergeben. Es wird nicht Kaskade durch ein Diagramm und den Zustand aller verwandten Objekte, im Gegensatz zu der DbSet.Add-Methode.

Das widerspricht, was in diesen Fragen erwähnt wird:

In all den Antworten der oben genannten Fragen, Alle Benutzer erwähnten, dass die Verwendung von System.Data.EntityState.Added genau dasselbe ist wie die Verwendung von DbSet.Add. Aber der Artikel, den ich zuerst erwähnte, besagt, dass die Verwendung von System.Data.EntityState.Added nicht durch den Graphen kaskadieren wird.

Basierend auf meinem Test, schließe ich, dass mit System.Data.EntityState.Added kaskadieren durch die Grafik wie im DBset.Add Fall. Ist der Artikel falsch, oder ist es mein Test und der Q & A?

Antwort

5

Diese Methoden sind die gleichen, die Sie durch regelmäßige Tests überprüfen können, oder, wenn Sie ganz sicher sein wollen - durch einige Erforschung von EF 6-Code.

  1. DbSet.Add Methode (http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/DbSet.cs)

    public virtual TEntity Add(TEntity entity) 
    { 
        Check.NotNull<TEntity>(entity, "entity"); 
        this.GetInternalSetWithCheck("Add").Add((object) entity); 
        return entity; 
    } 
    

Dies erfordert InternalSet<T>.Add(object) Methode.

  1. DbEntityEntry<T>.State Eigenschaft (http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Infrastructure/DbEntityEntry.cs)

    public EntityState State 
    { 
        get { return _internalEntityEntry.State; } 
        set { _internalEntityEntry.State = value; } 
    } 
    

Wo _internalEntityEntry von InternalEntityEntry Typ ist.

InternalEntityEntry.State Eigenschaft (http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Internal/EntityEntries/InternalEntityEntry.cs)

public virtual EntityState State 
    { 
     get { return IsDetached ? EntityState.Detached : _stateEntry.State; } 
     set 
     { 
      if (!IsDetached) 
      { 
       if (_stateEntry.State == EntityState.Modified 
        && value == EntityState.Unchanged) 
       { 
        // Special case modified to unchanged to be "reject changes" even 
        // ChangeState will do "accept changes". This keeps the behavior consistent with 
        // setting modified to false at the property level (once that is supported). 
        CurrentValues.SetValues(OriginalValues); 
       } 
       _stateEntry.ChangeState(value); 
      } 
      else 
      { 
       switch (value) 
       { 
        case EntityState.Added: 
         _internalContext.Set(_entityType).InternalSet.Add(_entity); 
         break; 
        case EntityState.Unchanged: 
         _internalContext.Set(_entityType).InternalSet.Attach(_entity); 
         break; 
        case EntityState.Modified: 
        case EntityState.Deleted: 
         _internalContext.Set(_entityType).InternalSet.Attach(_entity); 
         _stateEntry = _internalContext.GetStateEntry(_entity); 
         Debug.Assert(_stateEntry != null, "_stateEntry should not be null after Attach."); 
         _stateEntry.ChangeState(value); 
         break; 
       } 
      } 
     } 
    } 

Sie sehen, dass, wenn Einheit abgenommen wird (Ihr Fall) und Zustand hinzugefügt wird - die gleiche InternalSet<T>.Add(object) genannt wird.

Wie für die Überprüfung durch die Prüfung:

using (var ctx = new TestDBEntities()) { 
    // just some entity, details does not matter 
    var code = new Code(); 
    // another entity 
    var error = new Error(); 
    // Code has a collection of Errors 
    code.Errors.Add(error); 
    var codeEntry = ctx.Entry(code); 
    // modify code entry and mark as added 
    codeEntry.State = EntityState.Added; 
    // note we did not do anything with Error 
    var errorEntry = ctx.Entry(error); 
    // but it is marked as Added too, because when marking Code as Added - 
    // navigation properties were also explored and attached, just like when 
    // you do DbSet.Add 
    Debug.Assert(errorEntry.State == EntityState.Added);     
} 
+0

Sie sagen also, dass die Verwendung von EntityState.Added und die Verwendung von DBset.Add genau gleich sind? –

+1

Ja, wenn Ihre Entität nicht durch einen Kontext verfolgt wird, werden beide Methoden genau dasselbe tun, mit genau dem gleichen Ergebnis, was durch das Testbeispiel und die Exploration des Quellcodes bestätigt wird. – Evk

+0

also sagen wir, die Entität wird durch den Kontext verfolgt, dann werden sie sich unterscheiden? wie du sagtest "wenn deine Entität nicht verfolgt wird ..." –

5

Ich weiß nicht, den Autor dieses Blogs. Ich kenne die Autoren der book DbContext zwar (wenn auch nicht persönlich). Sie kennen EF von innen nach außen. Also, wenn auf Seite 80 schreiben sie

Aufruf DbSet.Add und Einstellung der State zu Added beide erreichen genau das Gleiche.

Ich weiß, was ich vorhabe. Sie tun genau das Gleiche, das ist:

Wenn das Unternehmen nicht durch den Kontext verfolgt wird, wird sie durch den Kontext in der Added Zustand verfolgt begonnen werden. Sowohl DbSet.Add und Einstellung der State zu Added sind Graph Operations- was bedeutet, dass alle anderen Unternehmen, die nicht durch den Kontext verfolgt werden und von der Root-Entität erreichbar sind, werden auch als Added markiert werden.

Ich weiß auch aus Erfahrung, dass es so funktioniert. Aber um jeden Zweifel zu beseitigen, im Quellcode der EF sowohl DbSet.Add und DbEntityEntry.State (wenn auf Added) in ObjectContext am gleichen Punkt ankommen, die die eigentliche Arbeit macht:

public virtual void AddObject(string entitySetName, object entity) 

Es ist eine Funktion, die Entwickler täuschen weiterhin, dass fange an, mit EF zu arbeiten, wie sich aus der großen Anzahl von Fragen bei StackOverflow ergibt, die etwas nach dem Motto "Wie kommt es, dass meine Entitäten dupliziert werden?" Julie Lerman schrieb eine entire blog, die erklärt, warum das passieren kann.

Diese fortgesetzte Wahnvorstellung ließ das EF-Team in EF7 auf change this behavior entscheiden.

Vielleicht war der Verfasser des Blogs, auf den Sie sich beziehen, einer dieser verblendeten Entwickler.