C# 将TSQL转换为Linq转换为实体
我有两个名为FileList和ExtensionsCategory的表:C# 将TSQL转换为Linq转换为实体,c#,entity-framework,linq,tsql,linq-to-entities,C#,Entity Framework,Linq,Tsql,Linq To Entities,我有两个名为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 及 表之间没有
FileList
-------------------------------------------------------------
ID Path Extension
1 C:\7.pdf pdf
2 D:\3.png png
3 C:\1.mp3 mp3
4 D:\32.pdf pdf
及
表之间没有任何关系
现在我想知道每个类别包含多少个文件?
我在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);
这将为您提供正确的结果:-
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()
};
或者,如果需要使用方法语法
:-
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到对象
更新:
如果类别可以包含多个扩展名,则可以使用以下查询:-
var result = extensionCat.GroupBy(x => x.Category)
.Select(x =>
new
{
Category = x.Key,
TotalFileCount = fileList.Count(f => x
.Any(z => z.Extension == f.Extension))
}
);
还有另一种方法可以更快地获得相同的结果 首先是
GroupBy
文件扩展名,然后在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]
@另一方面,拉胡辛格版本产生了以下结果:
-- 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行测试了这两个查询,结果如下: 与
ToList
版本相比:
在统计数据的最后几行中,您可以看到短版本大约快3倍。@MojtabaTajik-哪些数据?抱歉,我忘记了广告链接:认为我们在同一类别中有多个扩展。@MojtabaTajik-好的,检查我的更新,它会起作用。已经更新了小提琴。@MojtabaTajik-嘿,我已经再次更新了代码,这将更简单,应该也可以与EF一起使用。
-- 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]