2017-02-09 2 views
0

Ich bin ein Entity Framework (aktuelle Version 6) Neuling und versuchen, einige Abfragen zu tun..NET Entity Framework-Abfrage mit 2 Joins

Meine Datenbank sieht dies ähnlich:

enter image description here

ich eine Abfrage versucht (was nicht korrekt ist) wie:

Dim products = db.Product.Include(Function(p) p.Status).Include(Function(p) p.Status.StatusTranslations).AsExpandable().Where(predicate).Where(Function(p) p.Status.StatusTranslations.Language.Equals("en-Us")) 

wo AsExpandable() eine Funktion aus der LinqKit ist.

Dies ist, was ich in SQL wollen:

Select *, st.StatusDescription from Product As p 
Join Status As s On p.StatusId = s.Id 
Join StatusTranslations As st on s.Id = st.StatusId 
Where (...predicate...) And st.Language = 'en-US' 

so, dass ich die StatusDescription in meiner Ansicht angezeigt werden kann:

@ModelType IEnumerable(Of Product) 
... 
@For Each item In Model 
    @Html.DisplayFor(Function(modelItem) item.Status.StatusTranslations.StatusDescription) 
Next 

Meiner Ansicht erhalte ich die Fehlermeldung:

StatusDescription is not a member of ICollection(Of StatusTranslations)

Die Frage ist, wie sollte die vb.net-Abfrage aussehen, um dies zu erreichen und ist eine Änderung in der Datenbank Schema und/oder r Ansicht notwendig?

Antwort

0

Ihr Problem ist, dass gefiltert Include nicht unterstützt wird. Ich denke in diesem Fall ist die einfachste Sache, zuerst die Product s und Status es und dann die Übersetzungen zu laden. Ich werde Ihnen zeigen, wie es in C# tun:

var products = db.Products.Include(p => p.Status) 
        .AsExpandable() 
        .Where(predicate); 
var translations = products 
        .Select(p => p.Status.StatusTranslations 
           .FirstOrDefault(tran => tran.Language == "en-Us")) 
        .Load(); 

nun Ihrer Meinung nach, können Sie tun:

@For Each item In Model 
    @Html.DisplayFor(Function(modelItem) item.Status.StatusTranslations 
              .FirstOrDefault().StatusDescription) 
Next 

Die beiden LINQ-Abfragen die erforderlichen Daten in den Kontext laden. EF füllt die Navigationseigenschaften mit Relationship Fixup, so dass Sie tatsächlich item.Status.StatusTranslations.FirstOrDefault() finden können.

Eine wichtige Sache: Sie müssen zuerst ein träges Laden deaktivieren:

db.Configuration.LazyLoadingEnabled = false; 

Dies ist, weil die Navigationseigenschaften, obwohl sie bevölkert sind, nicht als geladen gekennzeichnet. Ihre Adressierung würde ansonsten immer noch zu einem verzögerten Laden führen.