2

Ich möchte eine potenziell sehr große Einfügung in meine Datenbank durchführen, basierend auf anderen Daten aus meiner Datenbank. Leistung ist wichtig für diese Anwendung, und selbst mit einem SqlBulkCopy verlangsamt diesen Prozess ein bisschen zu viel für meinen Geschmack.Verwenden von Entity Framework zum Ausführen von Befehlen in einer Datenbank

So die Frage: kann man Linq zu EF verwenden, um automatisch SQL-Code auf der Datenbank zu generieren und auszuführen, nie zurück etwas zurück zum Benutzer? Es scheint mir möglich zu sein, ich habe einfach keine Ahnung, wie ich es umgehen soll.

Hier ist die Prämisse: Könnte so etwas wie das Folgende jemals funktionieren?

myContext.OutputTable.AddRange(
    myContext.TableA.Join(
     myContext.TableB, 
     a => a.myAKey, 
     b => b.myBKey, 
     (a, b) => new { a.fieldA, a.fieldB, b.fieldC }).Select(
    output => new OutputTable 
    { 
     myOutputColumnA = output.FieldA, 
     myOutputColumnB = output.FieldB, 
     myOutputColumnC = output.FieldC 
    }) 
); 

Vielleicht ist das, was ich hier versuche, nicht offensichtlich. Ich versuche im Grunde, Daten in "OutputTable" unter Verwendung von Daten aus TableA und TableB einzufügen, ohne dass EntityFramework die Daten an die Anwendung zurückgeben kann. Jetzt weiß ich, dass es möglich ist, ExecuteNonQuery() zu verwenden, um diese Art von Insert-Anweisung auszuführen, aber letzten Endes möchte ich das aus verschiedenen Gründen nicht tun: Ich möchte den Code in C# vollständig beibehalten. Ich möchte auch den Debugging-Aspekt beibehalten, den Linq bietet (da ich Visual Studio verwende, hilft es, eine Abfrage an derselben Stelle fehlzuschlagen, an der der Code fehlschlägt).

Ich weiß, dass Linq to EF SQL generiert, die auf der Datenbank ausgeführt wird, so dass es mir möglich scheint, dies zu erreichen (müsste möglicherweise absichtlich lazy loading ignorieren, so dass der Code tatsächlich ausgeführt wird). Der obige Code wird nicht ausgeführt, ich glaube an die Prämisse, dass ein neues Objekt nicht innerhalb einer Select()-Anweisung auf diese Weise instanziiert werden kann (Linq an EF hat keine Ahnung, wie es damit umgehen soll). Ist dies letztendlich ein realisierbarer Weg, und wenn nicht, gibt es Alternativen?

+0

, wie viele Daten reden Sie? Hunderte? Tausende? Millionen? – Fran

+0

@Fran Realistisch, im Bereich Zehntausende bis Millionen. Das erste Mal, dass es läuft, kann mehrere zehn Millionen sein, obwohl ich nicht erwarte, dass es regelmäßig so groß ist. – LightToTheEnd

+0

Sie können dies nur erreichen, indem Sie eine gespeicherte Prozedur schreiben. Erwarten Sie nicht, dass eine sichere .Net-Anwendung Daten (d. H. Speicherinhalt) manipulieren kann, die sie selbst nicht besitzt. Wie auch immer, "Entity Framework" und "fast" ist ein Widerspruch in terminis. –

Antwort

1

Sie werden nicht schneller als SqlBulkCopy mit EF. EntityFramework ist ein ORM. Selbst wenn Sie alle möglichen Optionen ausschalten, wird es immer noch langsamer als SqlBulkCopy, weil es diese rohen SQL-Daten und Objekte materialisieren will.

SqlBulkCopy ist wie das Öffnen eines Firehose in der Datenbank. Es wird Einschränkungen deaktivieren und verwendet einen anderen Mechanismus, der regelmäßig in die Datenbank schreibt.

Alles, was schneller ist, müsste in der Datenbank enthalten sein, wie Gerts Kommentar erwähnt hat.

Hier ist eine alte, aber gute Erklärung von SqlBulkCopy hier

http://www.sqlbi.com/wp-content/uploads/SqlBulkCopy-Performance-1.0.pdf

Verwandte Themen