如何为以下 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 查询 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何为以下描述编写 mongodb 聚合查询

如何为以下查询编写QueryExpression?

如何为以下语句编写标准构建器 API JPA 查询

如何为实体框架 Sql 提供程序编写测试并访问生成的 Sql 命令

如何为每一行编写加入日期时间的 SQL 查询

如何为每个键进入 LINQ 一行