C# 如何在linq c中获取项目值和项目计数#

C# 如何在linq c中获取项目值和项目计数#,c#,linq,C#,Linq,我有一个名为hate的sql数据库表, 我想通过linq查询获得每个项目的名称及其计数 这就是我的代码: var qLocation = (from L in db.Hato where L.HatoRecDate >= startDate && L.HatoRecDate <= endDate group L by L.HatoLocation into g select new { Ha

我有一个名为hate的sql数据库表, 我想通过linq查询获得每个项目的名称及其计数 这就是我的代码:

var qLocation = (from L in db.Hato
         where L.HatoRecDate >= startDate && L.HatoRecDate <= endDate
                group L by L.HatoLocation into g
              select new { HatoLocation = g.Key, count = g.Count() })
.OrderByDescending(o => o.count).ToList();

var l = qLocation[0].HatoLocation;
var c = qLocation[0].count;
var qLocation=(从db.Hato中的L开始)
其中,L.HatoRecDate>=开始日期和&L.HatoRecDate o.count)。ToList();
var l=qLocation[0]。HatoLocation;
var c=qLocation[0]。计数;
它给了我项目名称;但显示任何项目计数的0结果 请告诉我我的代码哪里出了问题

更新 在反馈之后,我捕获了以下输出,有趣的是,只有集合中最后一条记录的计数为零:

试试这个。。。
执行.ToList()操作,然后执行group by。

您的代码看起来不错,我发现查询本身没有语法问题,您需要的是一些技巧来帮助您调试

当您使用内存中的记录集运行它时,它的行为符合预期,这意味着问题出现在生成的SQL中,您的Linq查询通过DbContext转换为SQL

作为你记忆中的证据,回顾一下这把小提琴:

尽管这对于生产代码来说不是一个好的实践,但解决并证明此问题是SQL问题的一种方法是在执行group by之前将数据读入内存。可以使用
.ToList()
IQueryable
表达式的结果加载到内存中

如果筛选条件没有问题,请在筛选条件之后调用
.ToList()
,而不是对整个表调用
.ToList()
。如果在调试会话之后意外地将其保留在代码中,其影响将小于从数据库中读取每条记录的影响

  • 您是按筛选器中聚合的结果排序的。这并不总是一个大问题,但如果您不同时使用限制因素,如
    TOP
    ,它通常会导致SQL的复杂性。一般来说,如果排序只影响渲染输出,而不影响功能逻辑,则应将排序过程留给渲染器。或者至少在内存中排序,而不是在SQL中排序

  • 原始查询将计算为类似以下内容的SQL:
    (我已经替换了开始和结束参数
    @p\u linq\u 0
    @p\u linq\u 1

    请用生成的SQL更新您的帖子,以便我们可以进一步探索

    更新 我已经用实际的DbContext实现更新了fiddle,但仍然无法生成计数为零的分组。


    这显示了如何提取SQL查询,但它表明代码中还有其他错误。我们要么需要查看更多的数据、更多的模式,要么在不分组的情况下查看数据的副本(如小提琴所示),这样我们就可以提供更多的帮助。

    什么是
    Hato
    def?什么是
    qLocation
    L
    L
    g
    o
    c
    ?哪种类型有
    HatoLocation
    ?HatoLocation是string?那么我看不出您的LINQ查询有问题。分析生成的SQL。您使用的是什么数据库引擎?我看不出怎么可能得到零'var qryLst=(从db.Hato中的L开始,其中L.HatoRecDate>=startDate&&L.HatoRecDate o.count);字符串l=qryCnt[0]。位置;int c=qryCnt[0]。计数;'我这样做了,但结果没有改变。谢谢亲爱的克里斯·沙勒。你的帮助解决了这个问题。再次感谢您如果有帮助,请将其标记为答案。不过我还是很好奇,你是如何具体解决的,我很想看看SQL,我只是看不出你是如何得到计数的零,除非这是一个空值比较问题。
    #region A safer way to bring the recordset into memory for debugging
    // Build the query in 2 steps, first create the filtered query
    var filteredHatoQuery = from L in db.Hato
                            where L.HatoRecDate >= startDate && L.HatoRecDate <= endDate
                            select L; 
                            // you could also consider only projecting the columns you need
                            // select new { L.HatoRecDate, L.HatoLocation };             
    // then operate on the data
    var qLocation = (from L in filteredHatoQuery.ToList()   // remove the .ToList() to query against the DB      
                     group L by L.HatoLocation into g
                     select new { HatoLocation = g.Key, count = g.Count() })
                    .OrderByDescending(o => o.count).ToList();
                     
    #endregion A safer way to bring the recordset into memory for debugging
    
    SELECT HatoLocation, COUNT(*)
    FROM Hato
    WHERE HatoRecDate >= '2021-05-21' AND HatoRecDate <= '2021-05-24'
    GROUP BY HatoLoction
    
    SELECT 
    [Project1].[C2] AS [C1], 
    [Project1].[HatoLocation] AS [HatoLocation], 
    [Project1].[C1] AS [C2]
    FROM ( SELECT 
        [GroupBy1].[A1] AS [C1], 
        [GroupBy1].[K1] AS [HatoLocation], 
        1 AS [C2]
        FROM ( SELECT 
            [Extent1].[HatoLocation] AS [K1], 
            COUNT(1) AS [A1]
            FROM [dbo].[Hato] AS [Extent1]
            WHERE ([Extent1].[HatoRecDate] >= '2021-05-21') AND ([Extent1].[HatoRecDate] <= '2021-05-24')
            GROUP BY [Extent1].[HatoLocation]
        )  AS [GroupBy1]
    )  AS [Project1]
    ORDER BY [Project1].[C1] DESC
    
    var qLocationQuery = from L in db.Hato
                         where L.HatoRecDate >= startDate && L.HatoRecDate <= endDate
                         group L by L.HatoLocation into g
                         select new { HatoLocation = g.Key, count = g.Count() };
    
    System.Diagnostics.Debug.WriteLine("Hato Query SQL:");
    System.Diagnostics.Debug.WriteLine(qLocationQuery.ToString());
    
    var qLocation = qLocationQuery.ToList();
    // now perform the sort, this simulates leaving the sort to the rendering logic.
    qLocation = qLocation.OrderByDescending(o => o.count).ToList();