2012-01-30 10 views
5

Jak sortować zapytanie z DbSet i uwzględniać elementy podrzędne, które również należy sortować.Zamawianie obiektów Elementy struktury i elementy potomne dla widoku MVC

Przykład:

Mam model do planowania zamówień.

public class Order 
{ 
    public virtual int Id { get; set; } 
    public virtual int? SchedulingOrder { get; set; } 
    public virtual int? WeekId { get; set; } 
    public virtual Week Week { get; set; } 
} 
public class Week 
{ 
    public virtual int Id { get; set; } 
    public virtual DateTime StartDate { get; set; } 
    public virtual ICollection<Order> Orders { get; set; } 
} 
... 
public DbSet<Week> Weeks { get; set; } 
public DbSet<Order> Orders { get; set; } 

Następnie metoda działania

public ActionResult ShopSchedule() 
{ 
    return View(db.Weeks.OrderBy(w => w.StartDate) 
       .Include(w => w.Orders.OrderBy(o => o.SchedulingOrder)) 
       .ToList()); 
} 

To nie działa myślę, ze względu na charakter Include. Czy muszę utworzyć osobny model widoku i mapować do niego? Czy jest jakiś sposób, aby ominąć to pytanie w zapytaniu? Jest jakaś składnia, w której ludzie mówią new { left = right, etc } w zapytaniu?

pokrewnych pytania:
Ordering Entity Framework sub-items for EditorFor
C# Entity Framework 4.1 Lambda Include - only select specific included values

+0

Nie sądzę, mogę przekazać anonimowe typy do widzenia, ponieważ HTML pomocnicy używać lambda jest. Zgaduję, że byłby z tym problem, ale może powinienem to sprawdzić. – Benjamin

+0

To samo pytanie: http://stackoverflow.com/questions/8447384/how-to-order-child-collections-of-entities-in-ef?rq=1 To samo pytanie, używając LINQ-to-Entities (podobne do SQL) składnia: http://stackoverflow.com/questions/3981417/how-to-sort-inner-list-that-is-return-by-entity-framework?rq=1 –

+0

Również http://stackoverflow.com/questions/7522784/ef-4-1-code-first-how-to-order-navigation-properties-when-using-include-and-or-lub/7528266 # 7528266 –

Odpowiedz

3

Masz rację, nie można używać poleceń w Include, nie jest przeznaczona do pracy w ten sposób. Ale możesz sortować wyniki w widoku przy użyciu OrderBy w zbiorze Zamówienia. Co więcej, zwracasz wynik bezpośrednio, czy nie powinien on być return View(db.Weeks...);

+0

oops, tak powinno się powiedzieć 'return View (etc)' Naprawię to i spróbuję go posortować w widoku. Dzięki. – Benjamin

+0

tak, działa! dzięki! – Benjamin

+0

Zauważ, że nie jest to bardzo wydajne - ładujesz elementy, które nie są uporządkowane, co często może być wolniejsze w SQL Server, a następnie porządkujesz je w pamięci - kiedy możesz używać bazy danych do tego, w czym jest dobra, zamawiając je w SQL w pierwszej kolejności (patrz moja odpowiedź). –

1

Coś jak to powinno działać:

public ActionResult ShopSchedule() 
{ 
    var vw = db.Weeks.OrderBy(w => w.StartDate) 
       .Include(w => w.Orders) 
       .ToList(); 
    vw.Orders = vw.Orders.OrderBy(o => o.SchedulingOrder).ToList() 
    return view(vw); 
} 
3

Warto zauważyć, że pozostałe 2 rozwiązania tutaj ciągnąć dane za pośrednictwem SQL, a następnie kolejność rzeczy w pamięci, co jest bardzo rozrzutny pod względem wydajności zarówno podczas zapytania i przetwarzanie końcowe. To rozwiązanie pozwala uzyskać wszystko za jednym razem, bez dodatkowego etapu w pamięci.

Można to zrobić w sposób opisany w drugim podejściu tutaj: How to order child collections of entities in EF

odczuwalna:

db.VendorProducts.Select(p => 
    new { Product = p, S = p.Schedules.OrderBy(s => s.From) }) 
    .FirstOrDefault(q => q.Product.Id == id).Product 

Więc zamiast include, należy wywołać odpowiednie dane w anonimowej obiektu wraz z oryginalne dane root, które chciałeś pobrać, zamówić je w tym podkwerendie i ostatecznie zwrócić dane root'a. Kolejność pozostaje nienaruszona. Skręcone, ale działa.

trzymać się oryginalnego kodu:

db.Weeks.Select(w => new { W = w, O = w.Orders.OrderBy(o => o.SchedulingOrder) }) 
    .OrderBy(q => q.W.StartDate).Select(q => q.W); 
Powiązane problemy