2016-05-06 6 views
3

Ich habe drei ModellklassenEntity Framework verschachtelt Navigationseigenschaften zählen nur

public class Item1{ 

    public int Id; 

    public List<Item2> Item2List { get; set; } 
} 

public class Item2{ 
    public int Id; 

    //this is the FK 
    public int Item1Id {get;set;} 

    public Item1 Item1 {get;set;} 

    //Not in db. Ignored field in EntityTypeConfiguration 
    public int Item3Count; 

    public List<Item3> Item3List { get; set; } 
} 

public class Item3{ 
    public int Id; 

    //this is the FK 
    public int Item2Id {get;set;} 

    public Item2 Item2 {get;set;}  
} 

ich die Liste der element1 zusammen mit Liste der damit verbundenen Element2, und laden Sie die COUNT von Item3List in Verbindung mit Artikel 2 ohne das Laden der zurückkehren wollen Artikel3Liste. Hier

ist, was ich jetzt tue:

public IEnumerable<Item1> GetItems() 
{ 
    return base.Query().Include(item1 => item1.Item2List.Select(item2 => item2.Item3List)).ToList(); 
} 

Das gibt mir die Liste aller drei Objekte element1, Element2 und Item3. Aber ich brauche nur die Anzahl von Item3List in Item3Count und nicht die gesamte Item3List-Liste. Wie kann ich das erreichen? Ich habe das unten versucht, aber es wirft Fehler.

return base.Query().Include(item1 => item1.Item2List.Select(item2 => new Item2 { 
Item3Count = item2.Item3List.Count() 
})).ToList(); 

Der Pfadausdruck muss mit einer Navigationseigenschaft bezieht von der Art definiert. Verwenden Sie gepunktete Pfade für die Referenznavigation Properties und den Operator Select für die Objektnavigation . Parametername: Pfad

Antwort

1

Was Sie wollen, ist nicht möglich. Natürlich können Sie eine nicht zugeordnete Eigenschaft in einer EF LINQ-Abfrage nicht auffüllen, da dies die Idee ist, sie nicht zuzuordnen. Aber das wusstest du schon.

Was würden Sie wirklich tun möchte, ist so etwas wie dieses:

context.Item1s.Select(item1 => new Item1 
{ 
    Id = item1.Id, 
    Item2s = item1.Item2List.Select(item2 => new Item2List 
    { 
     Id = item2.Id, 
     Item3Count = item2.Item3List.Count() 
    }) 
}) 

Aber EF erlaubt Ihnen nicht, eine Entität Objekt in einem EF-Abfrage zu konstruieren.

Die Alternativen sind nicht ansprechend.

Sie könnten eine Struktur anonyme Typen bauen ...

context.Item1s.Select(item1 => new 
{ 
    Item1 = item1, 
    Item2s = item1.Item2List.Select(item2 => new 
    { 
     Item2 = item2, 
     Item3Count = item2.Item3List.Count() 
    }) 
}) 

... und verwenden Sie diese Liste Item1 Objekte zu konstruieren, die jeweils ihre Item2List s von Item2 s mit Item3Count Werten.

besser, aber noch nicht in der Nähe, was ideal wäre, ist AutoMapper zu verwenden und die Entitäten DTOs Karte:

Mapper.CreateMap<Item1,Item1Dto>(); 
Mapper.CreateMap<Item2,Item2Dto>(); 

können Sie AutoMapper die Verwendung flattening featureItem3Count zu füllen.Um dies zu tun, sollte Item2Dto eine Eigenschaft haben Item3ListCount und AutoMapper wird dies in Item3List.Count() übersetzen.

+0

Danke! Ich war mir nicht sicher, ob es möglich ist, aber das musste ich wissen – codermav

0

Sie verwenden nicht die ef-Konventionen. Siehe hierzu https://msdn.microsoft.com/en-us/data/jj819164.aspx. Sie haben so etwas zu tun:


public class Item1{ 

    public int Item1Id{get;set;} 

    public ICollection<Item2> Item2s{ get; set; } 
} 

public class Item2{ 

    public int Item2Id{get;set;} 

    //Not in db. Ignored field in mapping 
    [NotMapped] 
    public int Item3Count => Item3s.Count; 

    //this is the FK 
    public int Item1Id{get;set;} 

    public Item1 Item1 {get;set;} 

    public ICollection<Item3> Item3s{ get; set; } 
} 

public class Item3{ 
    public int Item3Id; 

    //FK 
    public int Item2Id {get;set;} 

    public Item2 Item2 {get;set;} 

} 

Jetzt:

public IEnumerable<int> GetCounts() 
{ 
    //get the items1 including its List of item2 
    var items1 = base.Query().Include(item1 => item1.Item2s); 

    //get the counts 
    var counts = items1.Select(item1 => item1.Item2s.Select(item2 => item2.Item3Count)); 

    //now in counts you have what you want, do what you please with it 
    //and return it 
    return counts; 

}


Ich habe dies sollte nicht versucht Arbeiten für Sie.

+0

Entschuldigung, ich habe das vollständige Modell nicht veröffentlicht, aber es ist bereits so eingerichtet, wie Sie es mit Fremdschlüsseln und Navigationseigenschaften gezeigt haben. Die Eigenschaft 'Item3Count' wird in der Konfiguration des Entitätstyps auf Ignore gesetzt (this.Ignore (t => t.Item3Count)). Aber ich bekomme den folgenden Fehler "Ein angegebener Include-Pfad ist nicht gültig. Der EntityType 'Namespace.DataContext.Item2' deklariert keine Navigationseigenschaft mit dem Namen 'Item3Count'." Schätze deine Hilfe! – codermav

+0

Ich möchte das IEnumerable und nicht das IEnumerable zurückgeben. Auch habe ich Ihre aktualisierte Lösung versucht, aber es löst die Ausnahme "Wert kann nicht null sein, Parametername Quelle". Sieht so aus, als ob wir die Item3s nicht holen und versuchen, die Anzahl direkt zu erhalten, während Item3s null ist. Der Codeblock funktioniert einwandfrei, wenn Sie Item3s in Schritt 1 abrufen, aber das verhindert den Zweck. Ich versuche, eine Möglichkeit zu finden, IEnumerbale zurückzugeben, die Item2s und nur die Anzahl für Item3s enthält. Danke, dass du dich darum gekümmert hast! – codermav