如何在 C# 中从 Linq EF 实现上述 Json 输出

问题描述 投票:0回答:1

我是 .Net MVC 新手,并尝试获取两个表的 Linq 查询的 Json 输出。

{
  "data": [
    {
      "product_id": "1",
      "name": "Product 1",
      "image": "/Conten/product_image/1.jpg",
      "attrs": [
        {
          "id": "1",
          "weight": "500 Grams",
          "price": "1.300",
          "old_price": "1.300",
          "qty": "5"
        },
        {
          "id": "3",
          "weight": "1KG",
          "price": "1.300",
          "old_price": "1.300",
          "qty": "5"
        }
      ]
    },
    {
      "product_id": "2",
      "name": "Product 2",
      "image": "/Conten/product_image/2.jpg",
      "attrs": [
        {
          "id": "5",
          "weight": "250 Grams",
          "price": "0.700",
          "old_price": "0.700",
          "qty": "2"
        },
        {
          "id": "6",
          "weight": "2 KG",
          "price": "1.300",
          "old_price": "1.300",
          "qty": "1"
        }
      ]
    }
  ]
}

我有两张桌子

  1. tblProducts 包含产品 ID、名称、主图像

  2. tblProduct_attr 包含 id、product_id、attr_value、价格、旧价格、数量

tblProduct_attr 包含 1 个产品的多个属性。

这是我的两个表的 Linq 连接代码。

var _products = (from p in db.tblProducts
                 join a in db.tblProduct_attr on p.product_id equals a.product_id
                 select new
                 {
                     product_id = p.product_id,
                     name = p.name,
                     image = p.main_image,

                     id = a.id,
                     weight = a.attr_value,
                     price = a.price,
                     old_price = a.old_price,
                     qty = a.qty
                 }).ToList();
c# asp.net-mvc entity-framework linq
1个回答
0
投票

不要使用显式联接,设置导航属性关系并让 EF 管理联接并重新组合所需的投影。 JOIN 的问题在于,它会产生笛卡尔积,基本上是关系的扁平化版本,如果每个产品都有多个属性,则每个属性都会获得一行,并在单行中附加扁平化的产品详细信息,您希望在其中显示相关的层次结构。

您的产品实体应具有映射到 Product_Attr 表并连接到两个表中的 ProductId 的属性集合。

public virtual ICollection<ProductAttribute> Attributes { get; } = [];

从那里我们可以预测所需的输出:

var products = db.tblProducts
    .AsNoTracking() // recommended for read operations to avoid querying tracking cache.
    .Select(p => new
    {
         product_id = p.product_id,
         name = p.name,
         image = p.main_image,
         attrs = p.Attributes.Select(a => new 
         {
             id = a.id,
             weight = a.attr_value,
             price = a.price,
             old_price = a.old_price,
             qty = a.qty
         }).ToList()
   }).ToList();

在幕后,EF 将创建笛卡尔坐标,但将关系重新构建为所需的投影。 您还可以考虑添加

.AsSplitQuery()
来完全删除笛卡尔坐标,执行两个查询来构建产品和属性。

© www.soinside.com 2019 - 2024. All rights reserved.