【问题标题】:How do I group data from the database in a DTO?如何在 DTO 中对数据库中的数据进行分组?
【发布时间】:2020-05-16 11:26:01
【问题描述】:

如何在 dto 中对数据库中的数据进行分组?

例如,我希望我的输出是这样的:

{
    id: "random-id-tst",
    years: [
        {
            year: 1,
            productIds: ['guid-id-1', 'guid-id-2'],
        },
        {
            year: 2,
            productIds: ['guid-id-3'],
        }
    ]
}

但我很挣扎,尝试了很多事情,终于走到了这一步:

{
    id: "random-id-tst",
    years: [
        {
            year: 1,
            productIds: ['guid-id-1'],
        },
        {
            year: 1,
            productIds: ['guid-id-2'],
        },
        {
            year: 2,
            productIds: ['guid-id-3'],
        },
    ]
}
public class Order
{
    public Guid ID{ get; set; }

    public ICollection<OrderLine> OrderLines { get; set; }
}
public class OrderLine
{ 
    public Guid OrderID { get; set; }
    public Order Order { get; set; }
    public Guid ProductID { get; set; }
    public Product Product { get; set; }
    public int Year { get; set }
}
public class Product
{
    public Guid ID { get; set; }        
    public ICollection<OrderLine> OrderLines { get; set; }
}
 public class OrderDto
    {
        public Guid ID { get; set; }
        public IEnumerable<YearsDto> Years { get; set; }
    }
public class YearDto
{
    public int Year { get; set; }
    public ICollection<Guid> ProductIds { get; set; }
}

我尝试了很多东西,但每次都得到不同的错误。

这就是我所做的:

var orderLines = (await _context.OrderLine
    .Where(s => s.orderID == orderId)
    .ToListAsync()).GroupBy(ol => ol.Year);


var order = (await _context.Order
    .Where(order => order.ID == orderId)
    .Select(x =>
        new OrderDto()
        {
            ID = order.ID,
            Years = orderLines.Select(ss => new YearsDto()
            { 
                Year = 1,
            }),
        }
    ).FirstAsync());


return order;

如您所见,我对Year 进行了硬编码并且没有包含productIds,因为由于某种原因我无法引用ss.Yearss.Product,同样当我运行它时,它给了我一个错误: InvalidOperationException: variable '__Select_1' of type 'System.Collections.Generic.IEnumerable`1[YearsDto]' referenced from scope '', but it is not defined

有人可以为我指出如何解决我的问题的正确方向吗?

【问题讨论】:

    标签: c# entity-framework data-transfer-objects


    【解决方案1】:

    这段代码应该可以得到你需要的结果:

                var order = _context.OrderLine
                    .Include(o => o.OrderLines)
                    .Where(s => s.Id == orderId)
                    .First();
    
                var orderDto = new OrderDto()
                {
                    ID = order.Id,
                    Years = order.OrderLines.ToLookup(ol => ol.Year).Select(g => new YearDto() {Year = g.Key, ProductIds = g.ToList().Select(x => x.ProductID).ToList()})
                };
    
    

    【讨论】:

    • 不得不做一些改变,但现在可以了!非常感谢!
    【解决方案2】:

    在您的第一组中,您可能想要类似的东西

    var orderLines = (await _context.OrderLine
        .Where(s => s.orderID == orderId)
        .ToListAsync()).GroupBy(ol => ol.Year, (key, group) => new { Year = key, Items = group.ToList()});
    

    这样,您的最终对象将是一个可枚举的匿名项目,其中包含属于该年份的属性Year 和属性Items

    因此您的其余查询(只是为了使其编译并获取您需要的数据)可以转换为:

    var order = (await _context.Order
        .Where(order => order.ID == orderId)
        .Select(x =>
            new OrderDto()
            {
                ID = order.ID,
                Years = orderLines.Select(ss => new YearsDto()
                { 
                    Year = ss.Year,
                    ProductsIds = ss.Items.Select(i => i.ProductID)
                }),
            }
        ).FirstAsync());
    
    
    return order;
    

    【讨论】:

    • 仍然得到InvalidOperationException。得到它与kebek的答案一起使用。感谢您的宝贵时间!
    【解决方案3】:

    由于您的 OrderDto 中不需要任何额外数据,除了它的 ID(您已经拥有),您可以这样做:

    var years  = ( await _context.OrderLine
        .Where(s => s.orderID == orderId)
        .Select( ol => new {ol.Year, ol.ProductID})
        .ToListAsync())
        .GroupBy(ol => ol.Year)
        .Select(g =>  new YearDto 
        { 
             Year = g.Key, 
             ProductIds = g.Select(i => i.ProductID).ToList() }
        )
        .ToList();
    var orderDto = new OrderDto {ID = orderId; Years = years };
    

    虽然会丢失db中order存在的检查,但是可以单独查询。

    【讨论】:

      猜你喜欢
      • 2019-02-09
      • 1970-01-01
      • 2020-06-12
      • 2020-01-19
      • 2022-01-13
      • 2011-05-26
      • 2021-05-23
      • 2012-08-15
      • 2020-08-16
      相关资源
      最近更新 更多