背景
我在我的应用程序中记录搜索,并希望在统计视图中显示不同类型搜索之间的比率。
问题
我想在LINQ中保持尽可能高效和精简,但考虑到LINQ查询中可以使用的限制仍然保持清晰,所以我的尝试是这样的:
(请忽略我没有为搜索类型使用单独的实体的事实,这有其原因)
var result = MyEntities.Instance.SearchStatistics
.GroupBy(x => x.SearchType)
.Select(y => new List<string> { { y.Key }, { SqlFunctions.StringConvert((decimal)y.Count()).Trim() } })
.ToList();
return Json(new
{
Text = result.First(x => x.ElementAt(0) == "Text").ElementAt(1),
Organization = result.First(x => x.ElementAt(0) == "Organization").ElementAt(1),
Subject = result.First(x => x.ElementAt(0) == "Subject").ElementAt(1),
}, JsonRequestBehavior.AllowGet);
虽然这种行为方式出乎意料,但是列表列表中的结果列表在每个其他行中的值都被翻转了。
我预计 {{“Text”,“123”},{“Organization”,“123”},{“Subject”,“123”},...}
但取而代之的是 {{“Text”,“123”},{“123”,“Organization”},{“Subject”,“123”},...}
我不明白为什么,并试图对查询进行分区
var preresult = MyEntities.Instance.SearchStatistics
.GroupBy(x => x.SearchType).ToList();
var result = preresult
.Select(y => new List<string> { { y.Key }, { y.Count().ToString(CultureInfo.InvariantCulture) } }).ToList();
现在,只有在DB
中执行分组查询时,它才能正常工作将生成的LINQ查询的sql记录到数据库中,我得到了“错误”的结果:
SELECT [Project3].[SearchType] AS [SearchType],
[Project3].[C2] AS [C1],
[Project3].[C1] AS [C2]
FROM (SELECT CASE
WHEN ([UnionAll1].[C1] = 0) THEN [GroupBy1].[K1]
ELSE LTRIM(RTRIM(STR(CAST([GroupBy1].[A1] AS decimal(19, 0)))))
END AS [C1],
[GroupBy1].[K1] AS [SearchType],
1 AS [C2]
FROM (SELECT [Extent1].[SearchType] AS [K1],
COUNT(1) AS [A1]
FROM [app].[SearchStatistic] AS [Extent1]
GROUP BY [Extent1].[SearchType]) AS [GroupBy1]
CROSS JOIN (SELECT 0 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable1]
UNION ALL
SELECT 1 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable2]) AS [UnionAll1]) AS [Project3]
ORDER BY [Project3].[SearchType] ASC,
[Project3].[C2] ASC
不幸的是,我在SQL方面的经验有限,只是通过观察我的头疼,但显然有些事情变得混乱。
有人可以找出sql查询中的问题所在吗?
我希望这是否合理?它可能被视为一个错误,还是仅仅是我的期望在合同中没有支持LINQ应该如何工作?
更新
等一下,为什么我不直接查看SQL查询的输出?头脑以神秘的方式运作......
sql查询返回:
[SearchType, C1, C2]
{Text, 1, Text}
{Text, 1, 123}
{Organization, 1, 123}
{Organization, 1, Organization}
{Subject, 1, Subject}
{Subject, 1, 123}
但.ToList()之后的结果仍然只包含三个项目。这只会让我更加困惑,肯定一定是LINQ的一些隐含的内部行为会产生意想不到的后果吗?
答案 0 :(得分:1)
很难相信名称和值的顺序在JSON对象中被翻转,但显然它会发生。
这可能与List<T>
中的项目顺序永远不会保证等于广告订单的事实有关。您可以完全不使用列表来阻止此问题:
var result = MyEntities.Instance.SearchStatistics
.GroupBy(x => x.SearchType)
.Select(y => new { y.Key, Count = y.Count() })
.ToList();
return Json(new
{
Text = result.First(x => x.Key == "Text").Count.ToString(),
Organization = result.First(x => Key) == "Organization").Count.ToString(),
Subject = result.First(x => x.Key == "Subject").Count.ToString(),
}, JsonRequestBehavior.AllowGet);