2014-11-14 195 views
0

我有一個複雜的查詢。像LINQ Query查詢優化

我想檢查一個項目是否存在於基於密鑰和值的List (softwareLicencesList)內。但是,softwareLicencesList內的數據是加密的。所以首先我想解密它,然後在Dictionary (dict)內部查找以獲得映射值,然後驗證映射值與hardwareInfo Keys(hardwareInfo is a Dictionary which stores machine hardware information)。一旦密鑰驗證後,我想匹配的價值。

我寫了下面這段代碼來做到這一點。那麼這段代碼的作品,但我想知道它是否可以進一步優化。

foreach (var i in hardwareInfo) 
    { 
     if (!softwareLicencesList.Exists(x => dict.FirstOrDefault(y => y.Key == Crypt.Decrypt(x.Key, "Encryption Key")).Value == i.Key 
      && Crypt.VerifyHash(i.Value, "MD5", x.Value))) 
      { 
       //Do Something 
      } 
} 

Crypt.Decrypt()解密和驗證哈希Crypt.VerifyHash()的過程是複雜的。所以我想盡量減少對這些功能的調用次數。

+0

爲什麼你要解密整個列表?加密您的密鑰,並在列表中搜索它 – dotctor

+0

您的評論給了我一個想法,在字典Dictionary中保存加密值進行映射。所以......這樣我就可以節省解密所需的時間,並且可以直接映射Dictionary中存在的加密密鑰。 非常感謝! :) –

回答

0

您可以提高代碼中幾個位置的性能。您使用FirstOrDefault在匹配指定鍵的字典中查找值,但使用字典的整個要點是您在常量時間內可以查找指定鍵的值。此外,您不需要解密雙重嵌套循環內的軟件許可證密鑰。這是非常低效的。

因此,要改善你的代碼,你可以建立軟件許可證的列表與解密的密鑰:

var decryptedSoftwareLicenses = softwareLicenses 
    .Select(softwareLicense => 
    new { 
     DecryptedKey = Crypt.Decrypt(softwareLicense.Key, "Encryption key"), 
     SoftwareLicense = softwareLicense 
    } 
) 
    .ToList(); 

然後,您可以建立一個LINQ表達式來創建結果:

var results = hardwareInfos 
    .Where(hardwareInfo => 
    !decryptedSoftwareLicenses.Any(
     decrypted => 
     dictionary[decrypted.DecryptedKey] == hardwareInfo.Key 
     && Crypt.VerifyHash(hardwareInfo.Value, "MD5", decrypted.SoftwareLicense.Value) 
    ) 
); 

可以遍歷results使用foreach或應用ToList來執行實際計算。

請注意,我將變量名稱從i,xy更改爲更具描述性的內容。您選擇的名稱會讓您很難理解您的代碼。

+0

非常感謝您的詳細解釋!並且,我將繼續遵循更好的編程習慣。 –