2 Stimmen

Wie kann ich eine viele-zu-viele EntityCollection im Entity Framework effizient einrichten?

Wenn das Entity Framework einen ObjectContext für zwei Datenbanktabellen (sagen wir Table1 und Table2) generiert, die mit einer Many-to-Many-Beziehungstabelle verbunden sind, erstellt es kein Objekt für die XRef-Tabelle, sondern entscheidet sich stattdessen für Sammlungseigenschaften an jedem Ende der Beziehung. Also auf Table1 haben Sie EntityCollection Table2s und auf Table2 haben Sie EntityCollection Table1s. In den meisten Fällen ist das eigentlich ziemlich gut...

In diesem Szenario habe ich jedoch eine Liste von Ganzzahlen, die die Datenbank-IDs der Table2-Zeilen darstellen, die in der Table1.Table2s-Sammlung sein sollten.

Ich sehe keinen Weg, diese Sammlung einfach mit den Entity-Schlüsseln zu setzen, daher stecke ich fest und wähle diese in den ObjectContext aus, was bereits eine Menge Arbeit ist, die umsonst gemacht wird. Ich ließ mich hoffen, dass LINQ-to-Entities die Ausführung intelligent verschieben und alles auf dem SQL-Server ausführen wird, wie ich es gerne hätte (obwohl mein Where-Statement Contains verwendet, das möglicherweise korrekt in IN() in SQL übersetzt wird). Also kann ich so weit gehen wie:

table1instance.Table2s.Clear();
var table2sToInclude = context.Table2s.Where(
  t => 
  listOfTable2DatabaseIds.Contains(t.Id));

Aber es gibt kein EntityCollection.AddRange(IEnumerable) oder ähnliches, auch gibt es keine IEnumerable.ToEntityCollection() Erweiterungsmethode natürlich, also weiß ich nicht, was ich mit diesen Ergebnissen machen soll. Alles was ich tun kann ist

foreach (var table2 in table2sToInclude)
{
  table1instance.Table2s.Add(table2);
}

was lächerlich erscheint und ich weiß, dass es eine Menge unnötiger Auswertung erzwingen wird.

Gibt es einen "richtigen" oder vielleicht "weniger dummen" Weg, dies zu tun?

2voto

Ladislav Mrnka Punkte 355028

Nein, EF wird keine Abfrageausführung verzögern. Es gibt nichts wie ein Einfügen aus einem SELECT. Linq-to-Entities ist nur eine Abfragesprache und die Verantwortung der Abfrage besteht darin, sie auszuführen. Sie ist strikt von der Persistenzfunktionalität getrennt, die von EF selbst angeboten wird.

Wenn Sie Beziehungen zwischen einem vorhandenen Element aus Tabelle1 und vorhandenen Elementen aus Tabelle2 erstellen möchten, können Sie Code wie diesen verwenden:

using (var ctx = new YourContext())
{
    var table1 = new Table1 { Id = 123 };
    ctx.Table1s.Attach(table1);

    foreach (var table2 in table2sToInclude.Select(id => new Table2 { Id = id }))
    {
        ctx.Table2s.Attach(table2);
        order.Table2s.Add(table2);
    }
    ctx.SaveChanges();
}

Dieser Code erstellt eine Beziehung zwischen dem Element von Table1 mit der ID 123 und allen Elementen von Table2 aus table2sToInclude, ohne einen einzelnen Datensatz aus der Datenbank zu laden.

Was macht das Hinzufügen von Datensätzen nacheinander "lahm"? Verstehen Sie den Vorteil von AddRange? AddRange in einer typischen Sammlung erweitert die Kapazität des internen Arrays und kopiert einfach Elemente in das erweiterte Array. EntityCollection ist kein typisches Array und es muss jedes hinzugefügte Element verarbeiten. Auch wenn es einige AddRange gibt, wird es intern die Elemente durchlaufen und sie nacheinander verarbeiten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X