2015-10-21 97 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倍。