2013-12-09 128 views
2

我有下面的結構是對我的字典中的密鑰不能使用==:在LINQ擴展方法

public struct CodeAttribute 
{ 
    public int ProcessorId; 
    public Enums.TransactionType transactionType; 
    public string ErrorMessage; 
} 

我有以下字典(一個值作爲現在它只是爲例):

var errors = new Dictionary<CodeAttribute, int> 
{ 
    {CreateCodeAttributeList(2, Enums.TransactionType.Order, "Invalid ProcessorId sent in the Payment Request"), 100 } 
}; 

而且我試圖拔出項上有兩個其ProcessorId和TRANSACTIONTYPE特性匹配的結構相匹配的字典:

private static string GetRelatedMessage(int errorCode, Dictionary<CodeAttribute, int> errorsList) 
{ 
    CodeAttribute codeAttribute = errorsList.Where(e => e.Key.ProcessorId == _processorId) 
              .Where(e => e.Key.transactionType == _transactionType) == errorCode; 
    return codeAttribute.ErrorMessage; 
} 

我也想匹配錯誤代碼作爲過濾的一部分,而不僅僅是paymentprocessorId和transactionType,只是一個附註。字典中的項目必須匹配所有3個值才能在我們的案例中獲得正確的值。

UPDATE

我想這個問題,以及,是的,我得到它不能轉換IEnumerable的到CodeAtribute

CodeAttribute codeAttributes = errorsList.Where(e => e.Key.ProcessorId == _processorId) 
             .Where(e => e.Key.transactionType == _transactionType) 
             .Where(e => e.Value.Equals(errorCode)); 

UPDATE

與山姆的幫助下,我認爲這個錯誤可能工作

CodeAttribute codeAttribute = errorsList.FirstOrDefault(e => e.Key.ProcessorId == 
_processorId && e.Key.transactionType == _transactionType 
      && e.Value == errorCode).Key; 
+1

你會得到什麼錯誤? – MarcinJuraszek

+2

'where where子句返回'IEnumerable'不是單個值 – Grundy

+0

什麼是Where(e => e.Key.transactionType == _transactionType)== errorCode'應該表示什麼? – SLaks

回答

2

如果我理解正確的話,那麼你要

var codeAttribute = errorsList.FirstOrDefault(e => 
               e.Key.ProcessorId == _processorId 
              && e.Key.transactionType == _transactionType 
              && e.Value == errorCode); 

    if(codeAttribute == null) 
    { 
     //no item matches in the dictionary. 
    } 

return codeAttribute.Key.ErrorMessage; 

注意codeAttribute將是一個KeyValuePair所以你需要codeAttribute.Key.ErrorMessage爲您的返回值。

您不需要使用Where,因爲這將返回IEnumerable,因此如果您想要單個項目,這將不起作用。


+0

不知道我可以做&&在這裏... – PositiveGuy

+1

是的..首先或默認將採取返回布爾值的函數。 (如果你想IEnumerable返回,你也可以在'Where'中使用&&),你不需要使用兩個單獨的Where Where – Sam

1

你可能需要去是這樣的:

CodeAttribute codeAttribute = errorsList.FirstOrDefault(e => e.Key.ProcessorId == _processorId && e.Key.transactionType ==_transactionType) 
+0

這不會起作用,因爲你不會返回一個'KeyValuePair'而不是'CodeAttribute' – Sam

+0

right,我沒有注意到,他應該去var result = blah;然後從中獲得關鍵和價值,並創建他想要的對象。 – Aram

0

而其他的答案是正確的,可能會寫這樣的:

var errorMessage = errorsList 
     .Where(e => e.Key.ProcessorId == _processorId 
        && e.Key.transactionType == _transactionType 
        && e.Value == errorCode) 
     .Select(e => e.Key.ErrorMessage) 
     .FirstOrDefault(); 

也就是說,先將條件先過濾,然後從該結果集中選擇我想要的數據,然後獲取轉換數據的第一個結果(如果存在)。

由於IEnumerable查詢是懶惰那麼這仍然會停在第一個成功過濾的對象上。


因爲源是一個字典,它也可以是謹慎地設置一個相應的Equals/GetHashCode的和結構,使得它將被使用的代碼。