如何在 DTO 中对数据库中的数据进行分组?
How do I group data from the database in a DTO?
如何将数据库中的数据分组到 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.Year
或 ss.Product
,而且当我 运行 这个,它给了我一个错误:
InvalidOperationException: variable '__Select_1' of type 'System.Collections.Generic.IEnumerable`1[YearsDto]' referenced from scope '', but it is not defined
有人可以指出正确的方向来解决我的问题吗?
在你的第一组中,你可能想要
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;
这段代码应该能得到你需要的结果:
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()})
};
由于您不需要在 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中订单存在的校验,但是可以单独查询
如何将数据库中的数据分组到 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.Year
或 ss.Product
,而且当我 运行 这个,它给了我一个错误:
InvalidOperationException: variable '__Select_1' of type 'System.Collections.Generic.IEnumerable`1[YearsDto]' referenced from scope '', but it is not defined
有人可以指出正确的方向来解决我的问题吗?
在你的第一组中,你可能想要
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;
这段代码应该能得到你需要的结果:
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()})
};
由于您不需要在 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中订单存在的校验,但是可以单独查询