Linq 投影到 DTO 对象

Linq projection into DTO objects

TL;DR: 代码应该显示我的意图,它出错的地方在输出语句中,我正在尝试设置 StatusItemDTO,这应该包含来自匿名对象的所有字段,LocationName 除外。


我正在尝试查询我的数据库并使用投影仅提取我需要的字段。 预期结果是 LocationDTO 包装 StatusItemDTO。困难的部分是在一个查询中映射多个 DTO。

出问题的地方是在我试图设置 StatusItemDTO 的输出语句中,我不知道如何从字典值中找出来。 如果您查看此 post 底部的我的 DTO 类,您可以看到 StatusItemDTO 包含匿名对象的所有字段,LocationName 除外。我制作匿名对象的唯一原因是,如果我只是选择新的 StatusItemDTO,我不知道如何 "store" LocationName。

我非常有信心查询可以做得更短、更智能,但我对投影到 DTO 没有经验,希望你能提供帮助。

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
                     };

我的 DTO:

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; }
}

编辑:实体类

 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; }

}

您可以直接投射到 DTO 而无需像这样使用匿名类型:

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();