我是 .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"
}
]
}
]
}
我有两张桌子
tblProducts 包含产品 ID、名称、主图像
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();
不要使用显式联接,设置导航属性关系并让 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()
来完全删除笛卡尔坐标,执行两个查询来构建产品和属性。