C# 如何在linq c中获取项目值和项目计数#
我有一个名为hate的sql数据库表, 我想通过linq查询获得每个项目的名称及其计数 这就是我的代码: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
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中排序
(我已经替换了开始和结束参数
@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();