2013-04-26 11 views
5

Ich habe zwei Tabellen in meiner Datenbank: TPM_AREAS und TPM_WORKGROUPS. Zwischen diesen beiden Tabellen besteht eine Viele-zu-Viele-Beziehung, und diese Beziehungen werden in einer Tabelle mit der Bezeichnung TPM_AREAWORKGROUPS gespeichert. Diese Tabelle sieht wie folgt aus:Gibt es einen schnellen Weg, um jede Verbindung zwischen zwei Entitäten zu bekommen?

enter image description here

Was ich tun müssen, ist auf einmal alle diese Zuordnungen in den Speicher zu laden, auf die schnellste Art und Weise möglich. Als TPM_AREAWORKGROUPS ein Verein ist, kann ich nicht einfach sagen:

var foo = (from aw in context.TPM_AREAWORKGROUPS select aw); 

ich drei Möglichkeiten denken kann, um möglicherweise das zu tun, aber ich bin nicht ganz sicher, wie jeder von ihnen zu erreichen, noch welches ist das beste.

1) Legen Sie in jeder Arbeitsgruppe, einschließlich der zugehörigen Bereiche:

Etwas wie:

var allWG = (from w in context.TPM_WORKGROUPS.Include("TPM_AREAS") 
      where w.TPM_AREAS.Count > 0 
      select w); 
// Loop through this enumeration and manually build a mapping of distinct AREAID/WORKGROUPID combinations. 

Pro: Dies ist wahrscheinlich die Standard-EntityFramework Art, Dinge zu tun, und erfordert keine Ich möchte die Datenbankstruktur oder -zuordnungen ändern.

Nachteile: Konnte möglicherweise langsam sein, da die TPM_WORKGROUPS Tabelle ziemlich groß ist und die TPM_AREAWORKGROUPS Tabelle nur 13 Zeilen hat. Außerdem gibt es keine TPM_AREAWORKGROUPS Klasse, also müsste ich eine Sammlung von Tuples zurückgeben oder eine neue Klasse dafür erstellen.

2) Ändern Sie mein Modell

Idealerweise würde ich eine TPM_AREAWORKGROUP Klasse mögen, und eine context.TPM_AREAWORKGROUP Eigenschaft. Ich habe den Designer verwendet, um dieses Modell direkt aus der Datenbank zu erstellen, also bin ich mir nicht ganz sicher, wie man diese Force zu einem tatsächlichen Modell machen kann. Gibt es einen einfachen Weg, dies zu tun?

Vorteile: Es würde mir erlauben, direkt gegen diese Tabelle, in einer Zeile Code getan. Yay!

Nachteile: Zwingt mich, mein Modell zu ändern, aber ist das eine schlechte Sache?

3) Schrauben Sie es, verwenden Sie Raw SQL, um zu bekommen, was ich will.

Ich kann die StoreConnection Eigenschaft des Kontexts abrufen und CreateCommand() direkt aufrufen. Ich kann dann nur tun:

using (DbCommand cmd = conn.CreateCommand()) 
{ 
    cmd.CommandText = "SELECT AreaId, WorkgroupId FROM TPM_AREAWORKGROUPS"; 
    var reader = cmd.ExecuteReader(); 
    // Loop through and get each mapping 
} 

Vorteile: schnell, einfach, mich nicht erfordert mein Modell zu ändern.

Nachteile: Scheint Art von Hacky. Überall sonst im Projekt verwenden wir nur den Standard-Entity-Framework-Code, sodass dieser von der Norm abweicht. Es hat auch die gleichen Probleme wie die erste Option; Es gibt immer noch keine TPM_AREAWORKGROUPS Klasse.

Frage: Was ist die beste Lösung für dieses Problem?

Idealerweise würde ich gerne # 2 machen, aber ich bin mir nicht ganz sicher, wie ich mein Modell einstellen soll. Oder vielleicht kennt jemand einen besseren Weg als meine drei Möglichkeiten.

Antwort

3

Sie könnten tun:

var result = context 
    .TPM_WORKGROUPS 
    .SelectMany(z => z.TPM_AREAS.Select(z2 => new 
        { 
         z2.AREAID, 
         z.WORKGROUPID 
        })); 

Die übersetzte SQL wird eine einfache SELECT AREAID, WORKGROUPID FROM TPM_AREAWORKGROUPS sein.

über weitere Optionen:

  • Ich würde nicht Option 3) verwenden, weil ich persönlich raw SQL so weit wie möglich vermeiden, wenn Entity Framework (https://stackoverflow.com/a/8880157/870604 aus irgendwelchen Gründen sehen).

  • Ich würde nicht die Option 2) verwenden, weil Sie Ihr Modell ändern müssten, und es gibt eine einfache und effiziente Möglichkeit, nicht ändern zu lassen.

+0

Ah, das ist eine großartige Umsetzung der ersten Option. Ich denke, das wird am Ende die akzeptierte Antwort sein. –

+0

@MikeChristensen Ich redigierte Antwort, um einige Anmerkungen über andere 2 Wahlen zur Verfügung zu stellen. Ich würde hier wirklich LINQ zu Entitäten mit Ihrem aktuellen Modell verwenden. – ken2k

0

Wie sieht es mit der Verwendung der Projektion aus, um Daten zu laden?

Sie könnten tun, füllen Sie ein anonymen Objekt und arbeiten Sie dann damit, wie Sie möchten.

+0

Codebeispiel bitte? –

Verwandte Themen