2013-05-28 61 views
0

您好我正在嘗試使用Linq從列表中刪除「所有」實體。Linq刪除所有語句的結果

問題:我正在搜索在我的數據庫中擁有特定證書的用戶。事情是,它將逐行返回....但我需要檢查的是:如果用戶持有所有必需的證書。這應該檢查我的int數組。

這是我的數組:[3,5,16],現在我想刪除沒有列表中所有三個用戶的所有用戶。代碼中的數組名稱爲必填

我得到的listItems中回看起來像這樣

listitem.CertificateValue
listitem.Uid
listitem.NameOfPerson

所以basicly這個例子彼得三行在列表中,在此保留所有需要留在列表中的行。但是菲利普只有2行,因此他們都沒有填滿整個搜索條件,所以應該刪除這兩行。

另外copyOfMandatoryis只是爲了不要亂用原始集合,並導致預期(集合大小已更改)。

foreach (var item in copyOfMandatory) 
{ 
    if (!mandatoryusers.All(i => mandatory.Contains(i.CertificateValue) 
          || i.Uid == item.Uid)) 
    { 
     mandatoryusers.RemoveAll(i => i.Uid == item.Uid); 
    } 
} 

UPDATE removeall過就像一個魅力它是否如預期般不工作陳述。

這樣做不帶走列表中的任何一部分,我開始室內用& &,而不是||但是隻要滿足搜索標準,它就會殺死所有的東西,而不是最後遇到的人。

任何人都有關於如何做到這一點的提示?

+0

是必需的證書數組,即'[3,5,16]''是否必須? –

+0

對不起,不好意思! – 8bitcat

回答

1

我會嘗試這樣的事情

var uIdToRemove = mandatoryusers.GroupBy(m => m.Uid) 
        .Where(g => mandatory.Except(g.Select(s => s.CertificateValue)).Any()) 
        .Select(g => g.Key).ToList(); 

mandatoryusers.RemoveAll(x => uidToRemove.Contains(x.Uid)); 
+0

哇,像一個魅力工作!很好放! – 8bitcat

1

如果您的All條件已關閉,

if (!mandatoryusers.All(i => mandatory.Contains(i.CertificateValue) 
         || i.Uid == item.Uid)) 
{ 
    mandatoryusers.RemoveAll(i => i.Uid == item.Uid); 
} 

它需要與&&不是||,你應該調用Any()代替All()

if (!mandatoryusers.Any(i => mandatory.Contains(i.CertificateValue) 
          && i.Uid == item.Uid)) 
{ 
    mandatoryusers.RemoveAll(i => i.Uid == item.Uid); 
} 

希望我明白你的邏輯和問題正確。

+0

嗨!謝謝我首先嚐試了&&但它所做的只是從列表中除去最後兩行。就好像它一直在檢查所有的東西,但是當剩下的兩個只有兩個時,它就讓它通過。 – 8bitcat

+1

@CarlPalsson我更新了答案。我意識到你想要任何任何而不是所有的if語句。 – TyCobb

1

您的All調用不夠精細:它試圖確保所有條目始終存在......並非所有條目都存在。

嘗試每個條目轉換成詞典:

var dict = new Dictionary<int, List<ItemType>>(); 
foreach (var mandatoryItem in mandatoryItems) 
{ 
    List<ItemType> itemTypeValue = null; 
    if (!dict.TryGetValue(mandatoryItem.Uid, out itemTypeValue) 
    { 
     itemTypeValue = new List<ItemType>(); 
     dict.Add(mandatoryItem.Uid, itemTypeValue); 
    } 
    itemTypeValue.Add(mandatoryItem); 
} 

現在你把所有的ItemType在UID指示燈的關鍵。從這裏,使用LINQ:

mandatoryusers = mandatoryusers.Where(i => dict[i.Uid].All(x => mandatory.Contains(x.CertificateValue)); 
1

if說法是不正確的(如你所說) - 它試圖檢查所有項目是否包含與證書在mandatory中的ID,其中用戶標識是當前項目。你應該做的是過濾用戶名爲的第一個,然後檢查證書。 雖然我不這樣做。我倒是組的結果通過用戶再檢查證書

var usersWithAllCertificates = mandatoryUsers.GroupBy(mu => mu.Uid) 
      //Select the ones that have all 3 certificates 
      .Where(g => g.Select(u => u.CertificateValue) 
       .Intersect(mandatory).Count() == 3) 
      .Select(g => g.ToList()); 

Intersect運營商將結合清單,其結果將是在兩個列表相同的項目。因此,如果用戶擁有全部3個證書(3,5和16),則相交的結果將爲3個項目。 usersWithAllCertificates對象將包含您想要的所有用戶。這是明確選擇你想要的值,而不是刪除你不想要的值,這是一個更好的方法。請注意,這假設每個用戶只在列表中一次(即只有3個證書)

+0

@RaphaëlAlthaus哈!你是對的。我的意思是「相交」。謝謝! –