【问题标题】:Use Count in Linq returns different results than SQL query在 Linq 中使用计数返回与 SQL 查询不同的结果
【发布时间】:2017-01-05 10:34:05
【问题描述】:

我使用 Linqer 将 SQL 转换为 LinQ 但结果不一样 我的 SQL 查询:

    Select ChuyenNganh.ChuyenNganhID,ChuyenNganh.TenChuyenNganh,SoLuong= count(BaiBao.ChuyenNganhID )
from BaiBao right join ChuyenNganh on ChuyenNganh.ChuyenNganhID = BaiBao.ChuyenNganhID
group by  ChuyenNganh.ChuyenNganhID, ChuyenNganh.TenChuyenNganh

转换为 Linq

var queryChuyenNganh = from t in myPhanLoaiTaiLieuDataContext.ChuyenNganhs
                                   join t0 in myPhanLoaiTaiLieuDataContext.BaiBaos on new { ChuyenNganhID = t.ChuyenNganhID } equals new { ChuyenNganhID = Convert.ToInt32(t0.ChuyenNganhID) } into t0_join
                                   from t0 in t0_join.DefaultIfEmpty()
                                   group t by new
                                   {
                                       t.ChuyenNganhID,
                                       t.TenChuyenNganh
                                   } into g
                                   select new
                                   {
                                       ChuyenNganhID = (System.Int32)g.Key.ChuyenNganhID,
                                       g.Key.TenChuyenNganh,

                                       SoLuong  =(Int32)g.Count()
                                   };

结果:

Linq

SQL

谁能帮我修好?

【问题讨论】:

  • t0_join.DefaultIfEmpty() 将返回 0 个计数行的默认值,因此为 1
  • 我认为在你的 sql 查询中,你正确地加入了 BaiBao 和 ChuyenNganh,而在你 Linq 中,你正确地加入了 ChuyenNganh 和 BaiBao。右连接或左连接的订单事项,您正在计算基数(BaiBao.ChuyenNganhID)

标签: c# sql linq linqer


【解决方案1】:

SQL 查询很可能可以在没有group by 的情况下在 LINQ 中重写,但可以使用简单的 LINQ GroupJoin

但是转换的主要问题是 SQL COUNT(expr) 不计算 NULL 值,并且没有直接的 LINQ 等效项,因此需要条件 CountSum(我个人更喜欢后者因为通常它会转化为更好的 SQL)。

因此,您查询所需的最小更改是

group t by newgroup t0 by new

SoLuong =(Int32)g.Count()SoLuong = g.Sum(t0 => t0 != null ? 1 : 0)

附:如开头所述,我将尝试以下 LINQ 查询:

var queryChuyenNganh = 
    from t in myPhanLoaiTaiLieuDataContext.ChuyenNganhs
    join bb in myPhanLoaiTaiLieuDataContext.BaiBaos
    on t.ChuyenNganhID equals bb.ChuyenNganhID into t_BaiBaos
    select new
    {
        t.ChuyenNganhID,
        t.TenChuyenNganh,
        SoLuong = t_BaiBaos.Count()
    }; 

【讨论】:

    【解决方案2】:

    不同之处在于 SQL 对外部连接表中的列 BaiBao.ChuyenNganhID 中的非空值进行计数,而 LINQ 对所有记录进行计数。

    您还需要使 LINQ 计数非空值:

    var queryChuyenNganh = from t in myPhanLoaiTaiLieuDataContext.ChuyenNganhs
       join t0 in myPhanLoaiTaiLieuDataContext.BaiBaos
           on new { t.ChuyenNganhID } equals new { ChuyenNganhID = Convert.ToInt32(t0.ChuyenNganhID) } into t0_join
       from t0 in t0_join.DefaultIfEmpty()
       group new {T=t, NonNull=t0.ChuyenNganhID != null} by new
       {
           t.T.ChuyenNganhID,
           t.T.TenChuyenNganh
       } into g
       select new
       {
           ChuyenNganhID = (System.Int32)g.Key.ChuyenNganhID,
           g.Key.TenChuyenNganh,
           SoLuong  =(Int32)g.Count(x => x.NonNull)
       };
    

    【讨论】:

    • 我不这么认为。按 t 分组到 g 后,g 不包含 BaiBao.ChuyenNganhID 所以 g 没有非空值
    • @DiênCông 您是否阅读并理解了答案中的查询?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多