2014-11-14 197 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

非常感谢您的详细解释!并且,我将继续遵循更好的编程习惯。 –