2016-05-05 9 views
1

TL; DR: Der Code sollte meine Absicht zeigen, der Ort, an dem es schief geht, ist in der Ausgabeanweisung, wo ich versuche, die StatusItemDTOs, die alle Felder enthalten sollen die anonymen Objekte außer LocationName.Linq Projektion in DTO-Objekte


Ich versuche, meine db abzufragen und extrahieren nur die Felder, die ich brauche Projektion. Das beabsichtigte Ergebnis ist ein LocationDTO-Wrapping StatusItemDTOs. Der schwierige Teil besteht in der Zuordnung mehrerer DTOs in einer Abfrage.

Wo es schief geht ist in der Ausgabeanweisung, wo ich versuche, die StatusItemDTOs zu setzen, die ich keine Ahnung habe, wie aus den Wörterbuchwerten zu tun. Wenn Sie sich meine DTO-Klassen unten in diesem Beitrag ansehen, können Sie sehen, dass das StatusItemDTO alle Felder der anonymen Objekte enthält, mit Ausnahme von LocationName. Der einzige Grund, warum ich die anonymen Objekte mache, ist, weil ich nicht weiß, wie ich den LocationName "speichern" soll, wenn ich nur neue StatusItemDTOs auswähle.

Ich bin ziemlich zuversichtlich, dass die Abfrage kürzer und intelligenter durchgeführt werden kann, aber ich bin unerfahren mit der Projektion in DTOs und hoffe, Sie können helfen.

var query = (from liq in Context.LocationItemQuantities 
      where liq.Location.DepotId == depotId 
      select new 
      { 
      LocationName = liq.Location.Name, 
      ItemTypeName = liq.ItemType.Name, 
      DepotQuantity = liq.Quantity, 
      StandardQuantity = liq.StandardQuantity, 
      MinimumQuantity = liq.MinQuantity, 
      }).ToList(); 

     var output = from anon in query 
        group anon by anon.LocationName into g 
        select new LocationDTO 
        { 
         LocationName = g.Key, 
         StatusItemDTOs = g 
        }; 

Mein DTOs:

public class StatusItemDTO 
{ 
    public int DepotQuantity { get; set; } 
    public string ItemTypeName { get; set; } 
    public DateTime ExpirationDate { get; set; } 

    public int StandardQuantity { get; set; } 
    public int? MinimumQuantity { get; set; } 
} 

public class LocationDTO 
{ 
    public List<StatusItemDTO> StatusItemDTOs { get; set; } 
    public string LocationName { get; set; } 
} 

Edit: Entity Klassen

public class LocationItemQuantity : IEntity 
    { 
     public int Id { get; set; } 

     public int Quantity { get; set; } 

     public int? MinQuantity { get; set; } 

     public int StandardQuantity { get; set; } 

     public bool IsChecked { get; set; } 

     public int LocationId { get; set; } 

     public Location Location { get; set; } 

     public int ItemTypeId { get; set; } 

     public ItemType ItemType { get; set; } 

    } 

public class Location : IEntity 
    { 
     public int Id { get; set; } 

     public List<LocationItemQuantity> LocationItemQuantities { get; set; } 

     public string Name { get; set; } 

     public int? DepotId { get; set; } 

     public Depot Depot { get; set; } 

    } 

public class ItemType : IEntity 
{ 
    public int Id { get; set; } 

    public string InternBarcode { get; set; } 

    public string Description { get; set; } 

    public string Name { get; set; } 

    public List<LocationItemQuantity> LocationItemQuantities { get; set; } 

    public List<ProductBatch> ProductBatches { get; set; } 

    public List<Product> Products { get; set; } 

} 

Antwort

1

Sie in die DTOs direkt ohne die Verwendung von anonymen Typen wie dieses Projekt können:

var result = 
    Context 
    .LocationItemQuantities 
    .Where(x=> x.Location.DepotId == depotId) 
    .GroupBy(x => x.Location.Name) 
    .Select(x => new LocationDTO 
    { 
     LocationName = x.Key, 
     StatusItemDTOs = x.Select(y => new StatusItemDTO 
     { 
      DepotQuantity = y.Quantity, 
      StandardQuantity = y.StandardQuantity, 
      MinimumQuantity = y.MinQuantity, 
      ItemTypeName = y.ItemType.Name 
     }).ToList() 
    }) 
    .ToList(); 
+0

Dies tut in der Tat produzieren das gewünschte Ergebnis, aber in n + 1 SQL que Aufgrund des Aufrufs von ToList() bei der Auswahl der StatusItemDTOs. Wissen Sie, wie Sie dieses Problem vermeiden können? – Jenyoin

+0

Ich glaube nicht, dass das der Fall ist. Dies sollte in einer einzigen Abfrage geschehen. Haben Sie versucht, die Datenbank zu profilieren, um zu sehen, wie viele Abfragen gesendet wurden? –

+0

Bitte beachten Sie, dass die innere 'ToList()' in einem Ausdruck ist. –