sql - 为什么 LINQ Count() 返回多行而不是一行?

标签 sql linq count rows

我想将以下 SQL 转换为 LINQ:

    select  count(p.ID) as NumPosts,
            count(t.Trustee_ID)as TrusteePost,
            count(pat.ID)as PatientPost,
            count(s.ID) as SpecialistPost
           from [dbo].[Posts] as p 
    left join [dbo].[Trusteehips] as t
    on  p.Autor_ID = t.Trustee_ID
    left join [dbo].[Patients] as pat
    on  p.Autor_ID = pat.ID 
    left join [dbo].[Specialists] as s
    on  p.Autor_ID = s.ID
    where p.Deleted = 0

我已经尝试过这个:

var res = from p in context.Posts
                      join t in context.Trusteeships
                      on p.Autor.ID equals t.Trustee.ID into tGroup
                      join pat in context.Patients
                      on p.Autor.ID equals pat.ID into patGroup
                      join s in context.Specialists
                      on p.Autor.ID equals s.ID into sGroup
                      select new NumUserPosts
                      {
                          //CountAllPosts = ?
                          TrusteePost = tGroup.Count(),
                          PatientPost = patGroup.Count(),
                          SpecialistPost = sGroup.Count()
                      };

但结果是这样的:

1 0 0
0 0 1
0 0 1
0 1 0

and etc.

我期待结果

TrusteePost    PatientPost   SpecialistPost
    1000         2000            3000

为什么当我尝试计算组时返回此结果? SQL查询正确。我想翻译成LINQ。

最佳答案

查询返回每个加入的 Trustee 等 0 或 1 条记录,因为您通过唯一主键进行外部联接。因此,join into(在流畅语法中是 GroupJoin)会生成一组 0 或 1 条记录。如果您运行生成的 SQL 查询并查看原始查询结果,您可能会更好地了解发生了什么。

问题是,count(t.Trustee_ID) 等没有 LINQ 等效项。因此,如果不进行“黑客攻击”,就不可能在一个查询中完成您想要的操作。

将其破解为一个查询可以像这样完成:

(from p in context.Posts.Take(1)
select new 
{
  TrusteePost = context.Posts
                  .Count(p1 => context.Trusteeships.Any(x => x.ID == p1.Autor.ID)),
  PatientPost = context.Posts
                  .Count(p2 => context.Patients.Any(x => x.ID == p2.Autor.ID)),
  SpecialistPost = context.Posts
                     .Count(p3 => context.Specialists.Any(x => x.ID == p3.Autor.ID))
})
.AsEnumerable()
.Select(x => new NumUserPosts
{
  CountAllPosts = x.TrusteePost + x.PatientPost + x.SpecialistPost,
  x.TrusteePost,
  x.PatientPost,
  x.SpecialistPost
}

SQL 查询将比原始 SQL 更加复杂(例如,它涉及交叉联接),但它可能仍然会执行得很好。 AsEnumerable 阻止第二部分作为 SQL 执行,这会使 SQL 语句更加臃肿。它只是在内存中运行。

我认为这是一个黑客行为,因为第一部分 context.Posts.Take(1) 实际上没有任何意义,它只是充当三个单独查询的包装器。这是穷人的查询包装。

关于sql - 为什么 LINQ Count() 返回多行而不是一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29790199/

相关文章:

c# - 如何确保 Linq to Sql 不会覆盖或违反不可为 null 的数据库默认值?

c# - lambda 和 LINQ 之间的区别?

oracle - 根据多行的存在(序列号)从 SQL 中选择所有行

sql - 我发现了一个异常(exception)!!怎么办?

MySQL 选择帮助;子查询?

sql - 使用VB.NET访问远程sql服务器

c# - 在 Group By 中使用表达式树后无法选择

json - jq通过特定的key统计json中的item个数

sql - 在单个 SQL 查询中查找验证条件的行的比例

mysql - 如何知道在存储过程中插入查询是否成功?