10 Stimmen

Entity Framework 3.5 - Wie man Kinder lädt

Meine Fragen sind wahrscheinlich sehr einfach, wie laden Sie Kinder/Unterklassen. Es gibt kein "load" oder etwas ähnliches, das ich finden kann, um den Kontext die Kinder laden zu lassen.

die Kontextklasse ist vom Typ ObjectContext, siehe unten:

public partial class RTIPricingEntities : global::System.Data.Objects.ObjectContext

Produkt

Product.ModifiedByUser (wie wird diese Klasse beim Laden des Produkts geladen??)

Product.Category (wie lädt man die Kategorien beim Laden des Produkts?)

0 Stimmen

Hier ist ein Beispiel dafür, wie ich die Daten lade: Vielleicht sollte ich erwähnt haben, dass ich dies für eine Silverlight-Anwendung kodieren. Und dies ist durch einen Domainservice. RTIPricingContext _context = new RTIPricingContext(); LoadOperation<PurchaseOrder> op = _context.Load(context.GetPurchaseOrderQuery(), PurchaseOrdersLoadedCallback, null); private void PurchaseOrdersLoadedCallback(LoadOperation<PurchaseOrder> lo) { IEnumerable<PurchaseOrder> po = lo. Entities.Where(w => w.UserID == SelectedUser.ID); // Dies ist die Auflistung, die ich brauche, um die Unterklassen zu füllen.

16voto

Craig Stuntz Punkte 124703

Sie können eifrig laden:

var q = from p in Context.Products
                  .Include("ModifiedByUser")
                  .Include("Category")
        select p;

...oder Projekt:

var q = from p in Context.Products
        select new 
        {
           Id = p.Id,
           Name = p.Name
           ModifiedByUserName = p.ModifiedByUser.Name,
           CategoryName = p.Category.Name
        }

Der Vorteil der Projektion ist, dass Sie nur die Daten erhalten, die Sie benötigen, und nicht die Gesamtheit aller referenzierten Entitäten. Der Vorteil von Eager Loading ist, dass die zurückgegebenen Entitäten nachverfolgt werden können. Wählen Sie die richtige Technik für das jeweilige Problem.

Update

Ja, es でございます Es ist wichtig zu erwähnen, dass Sie RIA Services verwenden. Ich nehme an, Sie arbeiten auch innerhalb des Clients. Das macht die Dinge vollständig anders.

Bei RIA-Diensten ist es sehr wichtig, dass Sie beim ersten Laden den gesamten Graphen der benötigten Entitäten zurückgeben. Sie wollen nicht irgendetwas wie .Load() für eine Entität aufrufen, da dies eine weitere Anfrage an den Server wäre, was schlecht für die Leistung ist. Wenn Sie z.B. in einem Silverlight-Client sind und eine Liste von Instanzen vom Server anfordern und die zugehörigen Eigenschaften noch nicht materialisiert sind, ist es bereits zu spät. Außerdem funktioniert Include nicht in einem Silverlight-Client. Daher verfügen die RIA-Dienste über serverseitige Tools, mit denen Sie sicherstellen können, dass Sie anfangs den korrekten, vollständig materialisierten Objektgraphen zurückgeben.

Was Sie stattdessen tun müssen, ist IncludeAttribute innerhalb Ihres RIA Services Servers zu verwenden. Sie können eine "Buddy"-Metadatenklasse erstellen, um Ihr Entitätsmodell mit [Include] zu schmücken. Es gibt Beispiele in das Dokument mit der Übersicht über die RIA-Dienste, Abschnitt 4.8 .

0 Stimmen

Hallo, ich weiß nicht, ob wir die gleiche Version haben, aber keine der beiden Optionen ist möglich, wenn ich es codiere. Es gibt keine ".Include" verfügbar, nur "Intersect" .. im mit entityframework abgeleitete Entitäten, die "ObjectContext" als Basisklasse hat Und wenn ich projiziere, gibt es keine Eigenschaften in der Intellisense für mich zu setzen

1 Stimmen

Include ist eine Methode von ObjectQuery<T>, nicht von IQueryable<T>. Überprüfen Sie also den Typ des Verweises, den Sie haben. Entitäten leiten sich nicht von ObjectContext ab, sondern von EntityObject. In meinem Beispiel wird es kein IntelliSense für das projizierte Objekt geben, weil ich ein anonyme Typ. Wenn ich einen nicht-anonymen Typ verwendet hätte, gäbe es IntelliSense.

8voto

marc_s Punkte 701497

を使用しています。 .Include() wie viele andere vorgeschlagen haben, ist ein guter Weg, um das zu erreichen, was Sie brauchen.

Allerdings kann es vorkommen, dass Sie später etwas "nachladen" müssen, das Sie nicht "inkludiert" haben oder das Sie nur gelegentlich benötigen, so dass das Einfügen einer Include-Anweisung in vielen Fällen eine Verschwendung von Rechenzyklen darstellt.

Im Falle einer singulären Beziehung wie "Product.Category" (wobei Product.Category Ihre Navigationseigenschaft vom Produkt zur Kategorie ist), haben Sie höchstwahrscheinlich auch ein "Product.CategoryReference"-Element. Sie können prüfen, ob es geladen ist oder nicht, und wenn nicht, können Sie es "bei Bedarf" laden:

if(!Product.CategoryReference.IsLoaded)
{
    Product.CategoryReference.Load();
}

Jetzt sollte Ihre referenzierte "Kategorie" im Speicher sein und bereit zur Verwendung.

Wenn Sie eine Navigationseigenschaft haben, die auf eine Sammlung von Dingen verweist (z. B. "Teile" für ein Produkt), können Sie dasselbe tun, direkt auf der Navigationseigenschaft:

if(!Product.Parts.IsLoaded)
{
    Product.Parts.Load();
}

Das kann eine nützliche Technik sein, um einzelne oder sammlungsartige Navigationseigenschaften "bei Bedarf" zu laden, wenn Sie sie nicht in Ihre EF-Abfrage "einbezogen" haben.

Marc

0 Stimmen

Vielen Dank an alle, ich erkannte, dass der Grund, warum ich nicht in der Lage war, die vielen vorgeschlagenen Lösungen zu implementieren, ist, weil der Kontext anders ist, sobald durch den Domänendienst für Silverlight konvertiert. Im Code hinter dem Datenmodell des Entity Frameworks kann ich alle Ihre Lösungen implementieren und das habe ich gerade herausgefunden. Aber dank Ihrer Hilfe wusste ich, dass das Problem sein musste, dass ich an der falschen Stelle gesucht habe...

3voto

Daniel Richardson Punkte 4696

Sie können die Einschließen() Methode der System.Data.Objects.ObjectQuery . Diese Methode gibt die verwandten Objekte an, die in die Abfrageergebnisse aufgenommen werden sollen, und die Aufrufe von Include() können miteinander verkettet werden, um mehrere verwandte Objekte zu laden.

Um zum Beispiel ModifiedByUser und Category zu laden, würden Sie eine Abfrage wie diese verwenden:

var q = from p in context.Products.Include("ModifiedByUser").Include("Category") 
        select p;

Wenn Ihre Kategorie-Entität auch eine ModifiedByUser-Entität hat, die Sie laden möchten, würden Sie eine Abfrage wie diese verwenden:

var q = from p in context.Products
              .Include("ModifiedByUser")
              .Include("Category.ModifiedByUser") 
        select p;

Ver Gestaltung von Abfrageergebnissen auf MSDN für weitere Beispiele.

0 Stimmen

Ich sehe diese Lösung ziemlich oft, also muss ich etwas ganz anderes machen als alle anderen. Im Grunde genommen verwende ich den Kontext des Datenmodells, das vom Entityframework generiert wurde. Ich habe die neueste Version von .Net. Es ist kein "Include" verfügbar. Verwenden Sie dbml/linq in diesem Beispiel? Ich denke, das ist der Grund, warum es anders ist...

0voto

Johny Punkte 1

Ich habe festgestellt, dass die oben erwähnte Lösung von Craig nicht sowohl die ModifiedByUser- als auch die Category-Daten lädt. Sie lädt nur die letzte Objektsammlung, die in diesem Fall "Kategorie" ist.

var q = from p in Context.Products
              .Include("ModifiedByUser")
              .Include("Category")
    select p;

Wenn Sie jedoch die Reihenfolge vertauschen, so dass es .Include("Category").Include("ModifiedByUser") entonces ModifiedByUser geladen ist. Das Merkwürdige daran ist, dass die IsLoaded Eigenschaft beider Objektsammlungen wird "true" angezeigt, aber die Anzahl für die erste Objektsammlung wird immer Null sein. Ich bin mir nicht sicher, warum dies der Fall ist.

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