LINQ查询以在子项中包含父项名称
使用“连接”将两个模型连接起来,这样我们就可以连接每个属性,并将所有属性分组 数据由 OrderId和OrderDate,然后只需选择要显示的属性 关于礼物,您可以在选择中使用if-else 以下是我的演示:LINQ查询以在子项中包含父项名称,linq,asp.net-core,Linq,Asp.net Core,使用“连接”将两个模型连接起来,这样我们就可以连接每个属性,并将所有属性分组 数据由 OrderId和OrderDate,然后只需选择要显示的属性 关于礼物,您可以在选择中使用if-else 以下是我的演示: { "order": { "orderId": "123", "orderDate": "01-May-2021", "or
{
"order": {
"orderId": "123",
"orderDate": "01-May-2021",
"orderItems": [
{ "productName": "Pen", "quantity": "25", "retailPrice": "3.50" },
{ "productName": "Paper", "quantity": "500", "retailPrice": "5.50" },
]
}
}
结果:
您可以使用OrderDto来完成
[HttpGet]
public JsonResult Get()
{
var model = (from e in _context.OrderItems.Include(x=>x.Order).ToList()
join y in _context.Products.ToList() on e.OrderItemId equals y.ProductId
group new { e, y } by new { e.OrderId, e.Order.OrderDate } into g
select new
{
order = new
{
orderId = g.Key.OrderId,
orderDate = g.Key.OrderDate,
orderItems = (
from t in g.ToList()
select new
{
productName = t.e.Order.MarkAsPresent == true ? "Gift" : t.y.ProductName,
quantity = t.e.Quantity,
retailPrice = t.e.Price
}
).ToList()
}
}).ToList();
return new JsonResult(model);
}
将此方法添加到Order类
public class OrderDto
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public object OrderItems { get; set; }
public OrderDto(int orderId, DateTime orderDate)
{
OrderId = orderId;
OrderDate = orderDate;
}
}//Cls
//--------------------------------------------//
public class OrderItemDto
{
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal RetailPrice { get; set; }
public OrderItemDto(string giftName, int quantity, decimal retailPrice)
{
ProductName = giftName;
Quantity = quantity;
RetailPrice = retailPrice;
}
}//Cls
//--------------------------------------------//
public class GiftDto
{
public string GiftName { get; set; }
public int Quantity { get; set; }
public decimal RetailPrice { get; set; }
public GiftDto(string giftName, int quantity, decimal retailPrice)
{
GiftName = giftName;
Quantity = quantity;
RetailPrice = retailPrice;
}
}//Cls
目前给出的两个答案过于繁琐。有一种非常常见的标准方法: var result=从上下文中的o开始。顺序 选择新的 { o、 医嘱ID, o、 订单日期, 订单项= 来自o.OrderItems中的oi 选择新的 { ProductName=o.MarkAsPresent 礼物 :oi.Product.ProductName, oi.数量, 零售价 } };
您没有定义零售价格,所以我假设它只是OrderItem.Price。如果愿意,这两条select new语句可以被分别映射到OrderDto和OrderItemDto等命名DTO类的投影所替代。您还可以使用Linq:
我认为dotnetcore中的默认设置可以做到这一点。这与LINQ有什么关系?您是使用LINQ查询从数据库中选择此数据,还是内存中已经有C对象,只需要将它们转换为JSON?@brianberns是的,这些对象将从数据库中检索。@ShanieMoond您能解释一下吗?这些对象将从数据库中检索,如何检索?如果按实体框架,请选择适当的标记并说明确切的版本。不,不要使用join。始终使用导航属性。而且,两次使用ToList效率很低。“你应该尽可能长时间呆在IQueryable里。”蒂莎,非常感谢你的回复。我想第二行应该是:在e.ProductId上的_context.Products.ToList中加入y等于y.ProductId出于某种原因,我得到以下错误:System.Data.SqlTypes.SqlNullValueException:'数据为空。无法对Null值调用此方法或属性。此外,如果您还可以指定等效的LINQ方法语法,这将非常有用。非常感谢您的时间!非常感谢您抽出时间提供答案非常感谢您的回答。你的答案和ShanieMoont都起作用了。考虑到ShanieMoont为完成答案付出的额外努力,我不得不接受他的回答作为答案。我也非常感谢你的回答。非常感谢你!冗长vs简单,但好吧,你说了算。
public class OrderDto
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public object OrderItems { get; set; }
public OrderDto(int orderId, DateTime orderDate)
{
OrderId = orderId;
OrderDate = orderDate;
}
}//Cls
//--------------------------------------------//
public class OrderItemDto
{
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal RetailPrice { get; set; }
public OrderItemDto(string giftName, int quantity, decimal retailPrice)
{
ProductName = giftName;
Quantity = quantity;
RetailPrice = retailPrice;
}
}//Cls
//--------------------------------------------//
public class GiftDto
{
public string GiftName { get; set; }
public int Quantity { get; set; }
public decimal RetailPrice { get; set; }
public GiftDto(string giftName, int quantity, decimal retailPrice)
{
GiftName = giftName;
Quantity = quantity;
RetailPrice = retailPrice;
}
}//Cls
public class Order
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public bool MarkAsPresent { get; set; }
public List<OrderItem> OrderItems { get; set; }
public OrderDto ToDto()
{
var dto = new OrderDto(OrderId, OrderDate);
if (MarkAsPresent)
dto.OrderItems = OrderItems.Select(oi => new GiftDto(oi.Product.ProductName, oi.Quantity, oi.Price));
else
dto.OrderItems = OrderItems.Select(oi => new OrderItemDto(oi.Product.ProductName, oi.Quantity, oi.Price));
return dto;
}
}//Cls
[HttpGet]
[AllowAnonymous]
public IActionResult OrderGift()
{
var order = new Order()
{
OrderId = 1,
OrderDate = DateTime.Now,
MarkAsPresent = true
};
order.OrderItems = new List<OrderItem>();
for (int i = 0; i < 5; i++)
{
order.OrderItems.Add(
new OrderItem()
{
Order = order,
OrderId = order.OrderId,
OrderItemId = i + 10,
Price = (i + 1) * 10,
Product = new Product()
{
ProductId = i + 20,
ProductName = $"Name {i}"
},
ProductId = i + 20,
Quantity = i * 2 + 4
});
}//for
return Ok(order.ToDto());
}///OrderGift
[HttpGet]
[AllowAnonymous]
public IActionResult OrderRegular()
{
var order = new Order()
{
OrderId = 1,
OrderDate = DateTime.Now,
MarkAsPresent = false
};
order.OrderItems = new List<OrderItem>();
for (int i = 0; i < 5; i++)
{
order.OrderItems.Add(
new OrderItem()
{
Order = order,
OrderId = order.OrderId,
OrderItemId = i + 10,
Price = (i + 1) * 10,
Product = new Product()
{
ProductId = i + 20,
ProductName = $"Name {i}"
},
ProductId = i + 20,
Quantity = i * 2 + 4
});
}//for
return Ok(order.ToDto());
}//OrderRegular
var report =
from o in orders
let orderItems =
from oi in o.OrderItems
select new {
productName = o.MarkAsPresent ? "Gift" : oi.Product.ProductName,
quantity = oi.Quantity,
retailPrice = oi.Price
}
select new {
orderId = o.OrderId,
orderDate = o.OrderDate,
orderItems
};