2010-12-08 14 views
2

Ich habe ein Szenario, in dem ich ungefähr 7500 Datenbank-Datensätze abrufen muss, wobei jeder Datensatz 6 untergeordnete Entitätslisten hat. Jede dieser untergeordneten Listen kann 0 bis ungefähr 125 Datensätze umfassen.Was ist der effektivste Weg, Tausende von Datensätzen mit Hunderttausenden von Kinddatensätzen in Klassenobjekte zu ziehen?

Meine Klassenstruktur Art sieht aus wie folgt aus:

public class Entity 
{ 
    public int ID { get; set; 
    public string Name { get; set; } 
    public ICollection<ChildEntity1> Children1 { get; set; } 
    public ICollection<ChildEntity2> Children2 { get; set; } 
    public ICollection<ChildEntity3> Children3 { get; set; } 
    public ICollection<ChildEntity4> Children4 { get; set; } 
    ... 2 more collections 
} 

Nachdem ich alle Entitäten abzurufen, muss ich über jeden einzelnen zu durchlaufen und einige Berechnungen, rufen einige Web-Services und andere verschiedene Dinge ausführen und letztlich in eine Datei exportieren

Was sind die besten Strategien zum Abrufen dieser Daten von MS Sql Server 2008 mit C# 4? Ist ein DataSet mit DataAdapters der beste Weg? ORM?

Ich möchte aus naheliegenden Gründen weg von ausgewählten N + 1 Szenarien bleiben.

+1

Benötigen Sie alle Entitäten im Speicher zur gleichen Zeit oder können Sie eine Teilmenge von Entitäten abrufen, verarbeiten und in eine Datei schreiben? –

+0

Zum einen sollte Ihre Strategie nicht "alle Entitäten abrufen", gefolgt von "Iteration über alle". Gibt es einen Grund dafür, dass Ihr Algorithmus nicht immer hintereinander arbeiten kann, Zeile für Zeile? –

+0

@ Gilbert- Es wäre möglich, eine Teilmenge, sagen wir 100 zu einer Zeit, zu holen und zu einer Liste hinzuzufügen, um am Ende exportiert zu werden. Die Elterneinheit mit ihren Kindern ist vollständig atomar. –

Antwort

0

Also, was ich am Ende dabei wurde ein verschachteltes Datareader hat, eine Außen eine für das Mutterunternehmen alle Eltern zu bekommen, und dann eine innere, die den Leser alle Kinder in einer Anweisung liest mit .NextResult() -Methode wie folgt aus:

var exampleSql = "select * from child1Table; " + 
       "select * from child2Table; " + 
       "select * from child3Table"; 
       // and so on for the other child tables 
using (var outerReader = cmd.ExecuteReader()) 
{ 
    while (outerReader.Read()) 
    { 
     var entity = new Entity(); 
     entity.Prop1 = outerReader[0]; 
     entity.Prop2 = outerReader[1]; 
     //.... etc. 

     using (var cmdInner = new SqlCommand(exampleSql)) 
     using (var innerReader = cmdInner.ExecuteReader()) 
     { 
      while (innerReader.Read()) 
      { 
       var child = new Child1(); 
       child.Prop1 = innerReader[0]; 
       // ... etc. 
       entity.Children1.Add(child); 
      } 
      innerReader.NextResult(); 
      while (innerReader.Read()) 
      { 
       var child = new Child2(); 
       child.Prop1 = innerReader[0]; 
       // ... etc. 
       entity.Children2.Add(child); 
      } 
      innerReader.NextResult(); 
      // and so on for the other child entities 
     } 
    } 
} 

mindestens diese Weise bin ich nur eine sQL-Anweisung an die Datenbank zu senden alle mein Kind Einheiten pro Elternteil abgerufen werden statt einer gesonderten Erklärung pro Kind und Eltern .

Wenn jemand einen besseren Weg hat, bitte zögern Sie nicht, lassen Sie es mich wissen.

Btw, meine Beispielcode ist nur Pseudocode. Die wirkliche Sache ist die Verwendung parametrisierter Abfragen und keine Auswahl von Sternen, nur die Spalten, die ich brauche. Die Absicht ist, den Ansatz und nicht die tatsächliche Implementierung zu zeigen.

0
DECLARE CURSOR on the Entity. 

OPEN CURSOR. 

For each FETCH CURSOR 

    SELECT the child rows for the current Entity. 

    Write the output. 

CLOSE CURSOR.