如何为以下 Scenerio 编写 linq 查询 [关闭]
Posted
技术标签:
【中文标题】如何为以下 Scenerio 编写 linq 查询 [关闭]【英文标题】:How to write a linq query for below Scenerio [closed] 【发布时间】:2021-11-07 21:44:22 【问题描述】:我正在尝试将 SQL 查询转换为 Linq,但我不确定是否有办法编写此查询。此外,此查询仅从 CartonDetails 表中获取匹配值,但我需要 Carton 表中的所有值。
select Carton.Id,
Carton.CartonNumber,
COUNT(CartonDetail.CartonId) as TotalCount
from Carton
Inner Join CartonDetail on CartonDetail.CartonId = Carton.Id
Group by Carton.Id, Carton.CartonNumber
这就是我到目前为止所拥有的。我是 Linq 的新手。提前致谢
var apv = db.Cartons.Where(c => c.CartonDetails.Select(cd => cd.CartonId).Contains(c.Id)).GroupBy(c => c.Id, c => c.CartonNumber).Select(c => new CartonViewModel
Id = c.Key,
EquipmentCount = c.Count(),
// How can i select the Carton Number here.
);
return View(cartons);
CartonDetail.cs
[Table("CartonDetail")]
public partial class CartonDetail
public int Id get; set;
public int CartonId get; set;
public int EquipmentId get; set;
public Carton Carton get; set;
public Equipment Equipment get; set;
【问题讨论】:
这能回答你的问题吗? Group By Multiple Columns 旁注:COUNT(CartonDetail.CartonId)
将计算CartonId
的非空值。如果是不可为空的列,则与COUNT(*)
或COUNT(1)
相同
为什么要在two accounts下运营?
如果从 LINQ 查询中删除连接并将其转换为导航属性,则不需要分组。请阅读如何做到这一点here。它将简化您在 EF 中所做的一切。
【参考方案1】:
根据@GertArnold 的评论,最终的 linq 查询应该是这样的:
var apv = db.Cartons
.Select(c => new CartonViewModel
Id = c.Id,
CartonNumber = c.CartonNumber,
EquipmentCount = c.CartonDetails.Count()
);
return View(cartons);
【讨论】:
由于Select ... new
,包含在这里什么都不做。所以它不会“得到匹配的 CartonDetails”。
@GertArnold 是的,你是对的。在一对多关系的情况下,Include
主要使用Left join
转换为 T-Sql(因为 OP 要求所有Cartons
有或没有CartonDetails
),而且我认为Include
更具可读性。
我的意思是:EF 由于投影而忽略了 Include。即使将它包含在查询中,它也是一个外连接并且没有过滤效果。在发布之前测试您的代码,即使它看起来很简单。此外,计数不正确。
@GertArnold 哦,是的,当使用Count(CartonDetail.CartonId)
时,它只计算非空记录。答案已更新。
@GertArnold 感谢您分享 StackOwerflow 的知识。【参考方案2】:
如果您使用这些属性的匿名类型进行分组,它将是分组键。然后您可以从中获取值:
var apv = db.Cartons
.Join(db.CartonDetails,
c => c.Id,
cd => cd.CartonId,
(c, cd) => new c, cd)
.GroupBy(temp => new temp.c.Id, temp.c.CartonNumber)
.Select(c => new CartonViewModel
Id = c.Key.Id,
CartonNumber = c.Key.CartonNumber,
EquipmentCount = c.Count(),
);
这应该得到您原始查询的几乎准确的翻译。
【讨论】:
你是对的,没有意识到它是从另一个表开始而不是加入以上是关于如何为以下 Scenerio 编写 linq 查询 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章