2015-10-21 92 views
2

我有一个名为的文件列表并ExtensionsCategory 2表:转换TSQL到LINQ到实体

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到实体写吧,这是我的代码,但我无法完成它:

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); 

回答

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() 
         }; 
        }); 

Fiddle使用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)) 
          } 
        ); 
+0

@MojtabaTajik - 哪些数据? –

+0

对不起,我忘了广告链接:https://dotnetfiddle.net/FJCIm9 认为我们在同一类别中有多个扩展名。 –

+0

@MojtabaTajik - 好吧检查我的更新,它会工作。已经更新了小提琴。 –

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] 

Groupped Files

@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行测试,查询和结果是:

Client Statistics - Fast

主场迎战ToList版本:

Client Statistic - Slow

在统计的最后一行你可以看到短版版本快了大约3倍。