Frage

Ich möchte wissen, warum Code -Fragment 1 schneller als Code 2 verwendet wird, indem PoCOs mit Devart DotConnect für Oracle verwendet werden.

Ich habe es ausprobiert über 100000 Datensätze und Code 1 ist viel schneller als 2. Warum? Ich dachte, "Savechanges" würde den Puffer klarstellen, was es schneller macht, da es nur eine Verbindung gibt. Liege ich falsch?

Code 1:

        for (var i = 0; i < 100000; i++)
        {
            using (var ctx = new MyDbContext())
            {
                MyObj obj = new MyObj();
                obj.Id = i;
                obj.Name = "Foo " + i;
                ctx.MyObjects.Add(obj);
                ctx.SaveChanges();
            }
        }

Code 2:

        using (var ctx = new MyDbContext())
        {
            for (var i = 0; i < 100000; i++)
            {
                MyObj obj = new MyObj();
                obj.Id = i;
                obj.Name = "Foo " + i;
                ctx.MyObjects.Add(obj);
                ctx.SaveChanges();
            }
        }
War es hilfreich?

Lösung

Der erste Code-Snippet funktioniert schneller, da die gleiche Verbindung jedes Mal aus dem Pool genommen wird, sodass die Wiedereröffnung keine Leistungsverluste enthält.

Im zweiten Fall werden 100000 Objekte allmählich zum Kontext hinzugefügt. Es wird eine langsame Snapshot-basierte Verfolgung verwendet (wenn kein dynamischer Proxy). Dies führt zu der Erkennung, wenn sich bei jedem Savechanges () Änderungen in einem von zwischengespeicherten Objekten () ändern. Immer mehr Zeit wird von jeder nachfolgenden Iteration verbracht.

Wir empfehlen Ihnen, den folgenden Ansatz auszuprobieren. Es sollte eine bessere Leistung haben als die genannten:

using (var ctx = new MyDbContext())
    {
        for (var i = 0; i < 100000; i++)
        {
            MyObj obj = new MyObj();
            obj.Id = i;
            obj.Name = "Foo " + i;
            ctx.MyObjects.Add(obj);                
        }
        ctx.SaveChanges();
    }

BEARBEITEN

Wenn Sie einen Ansatz mit der Ausführung einer großen Anzahl von Vorgängen innerhalb eines Savechanges () verwenden, ist es nützlich, zusätzlich das Entity -Framework -Verhalten von Devart DotConnect für den Oracle -Anbieter zu konfigurieren:

// Turn on the Batch Updates mode:
var config = OracleEntityProviderConfig.Instance;
config.DmlOptions.BatchUpdates.Enabled = true;

// If necessary, enable the mode of re-using parameters with the same values:
config.DmlOptions.ReuseParameters = true;

// If object has a lot of nullable properties, and significant part of them are not set (i.e., nulls), omitting explicit insert of NULL-values will decrease greatly the size of generated SQL:
config.DmlOptions.InsertNullBehaviour = InsertNullBehaviour.Omit;

Hier werden nur einige Optionen erwähnt. Die vollständige Liste davon ist in unserem Artikel verfügbar:http://www.devart.com/blogs/dotconnect/index.php/new-featuresof --entity-framework-support-in-t--stotconnect-providers.html

Bin ich falsch anzunehmen, dass Savechanges () aufgerufen wird, alle Objekte im Cache in DB gespeichert und der Cache gelöscht wird, sodass jede Schleife unabhängig ist?

Savechanges () sendet und begeht alle Änderungen an die Datenbank, aber für alle Entitäten, die dem Kontext beigefügt sind, wird jedoch die Verfolgung von Änderungen fortgesetzt. Und neue Savechanges, wenn eine Schnappscheide-basierte Änderungsverfolgung verwendet wird, wird ein langer Überprüfungsvorgang (geändert oder nicht?) Die Werte jeder Eigenschaft für jedes Objekt starten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top