我有两个名为FileList和ExtensionsCategory的表:
FileList
-------------------------------------------------------------
ID Path Extension
1 C:\7.pdf pdf
2 D:\3.png png
3 C:\1.mp3 mp3
4 D:\32.pdf pdf
和
ExtensionsCategory
------------------------------------------------------------
ID Extension Category
1 mp3 Multimedia
2 pdf Document
3 png Photo
表之间没有任何关系。
现在我想知道每个类别包含多少个文件? 我在SSMS中编写了以下TSQL查询并且工作正常:
SELECT
Category
,SUM(FileCount) AS TotalFileCount
FROM
(SELECT
COUNT(*) AS FileCount
,(SELECT ExtensionsCategories.Category FROM ExtensionsCategories WHERE FileList.Extension = ExtensionsCategories.Extension) AS Category
FROM FileList GROUP BY Extension) AS T1 GROUP BY Category
我想知道在没有加入的情况下有没有改进的方法呢?
我尝试使用Linq to Entities编写它,这是我的代码,但我无法完成它:
var a = _dbContext.FileLists
.Select(fl => new
{
Extension = fl.Extension,
Count = _dbContext.FileLists.Count(),
Cat =
_dbContext.ExtensionsCategories.Where(w => w.Extension == fl.Extension).Select(s => s.Category)
}).GroupBy(g => g.Extension);
答案 0 :(得分:1)
这应该给你正确的结果: -
var result = from f in _dbContext.FileLists
group f by f.Extension into g
let firstCategory = _dbContext.ExtensionsCategories
.FirstOrDefault(x => x.Extension == g.Key)
select new
{
Category = firstCategory != null ? firstCategory.Category : "",
TotalFileCount = g.Count()
};
或者如果您需要Method Syntax
: -
var result = _dbContext.FileLists.GroupBy(e => e.Extension)
.Select(x =>
{
var firstCategory = _dbContext.ExtensionsCategories
.FirstOrDefault(z => z.Extension == x.Key);
return new
{
Category = firstCategory != null ? firstCategory.Category : "",
TotalFileCount = x.Count()
};
});
使用Linq-to-objects
<强>更新强>
如果某个类别可以包含多个扩展名,那么您可以使用以下查询: -
var result = extensionCat.GroupBy(x => x.Category)
.Select(x =>
new
{
Category = x.Key,
TotalFileCount = fileList.Count(f => x
.Any(z => z.Extension == f.Extension))
}
);
答案 1 :(得分:1)
还有另一种方法可以获得更快的相同结果。
第一个GroupBy
文件扩展名和Count
个GroupBy
元素选择器内的文件扩展名。在那里,您还可以获取这些文件扩展名中的键的类别名称:
var result =
Files
.GroupBy(x => x.Extension, (ext, fs) => new
{
Extension = ext,
Category = Categories.Single(c => c.Extension == ext).Name,
FileCount = fs.Count()
});
这将产生以下查询:
SELECT [t1].[Extension], (
SELECT [t2].[Name]
FROM [Category] AS [t2]
WHERE [t2].[Extension] = [t1].[Extension]
) AS [Category], [t1].[value] AS [FileCount]
FROM (
SELECT COUNT(*) AS [value], [t0].[Extension]
FROM [File] AS [t0]
GROUP BY [t0].[Extension]
) AS [t1]
另一方面,@ RahulSingh版本产生了这个:
-- Region Parameters
DECLARE @p0 NVarChar(1000) = ''
-- EndRegion
SELECT
(CASE
WHEN EXISTS(
SELECT TOP (1) NULL AS [EMPTY]
FROM [Category] AS [t2]
WHERE [t2].[Extension] = [t1].[Extension]
) THEN (
SELECT [t4].[Name]
FROM (
SELECT TOP (1) [t3].[Name]
FROM [Category] AS [t3]
WHERE [t3].[Extension] = [t1].[Extension]
) AS [t4]
)
ELSE CONVERT(NVarChar(50),@p0)
END) AS [Category], (
SELECT COUNT(*)
FROM [File] AS [t5]
WHERE (([t1].[Extension] IS NULL) AND ([t5].[Extension] IS NULL)) OR (([t1].[Extension] IS NOT NULL) AND ([t5].[Extension] IS NOT NULL) AND ([t1].[Extension] = [t5].[Extension]))
) AS [TotalFileCount]
FROM (
SELECT [t0].[Extension]
FROM [File] AS [t0]
GROUP BY [t0].[Extension]
) AS [t1]
我用1.000.000行测试了两个查询,结果是:
VS。 ToList
版本:
在统计信息的最后几行中,您可以看到 short 版本的速度提高了约3倍。