Dot-Net

lambda中的C#linq表達式包含

  • February 20, 2014

我正在嘗試利用“包含”來模擬舊 SQL 的“where id in (1,2,3,4)”過濾查詢的方式。

但是,在我的 id 處於更深層次的情況下,我在使用它時遇到了一些困難。

程式碼:

public class Category
   {
       public long Id { get; set; }
       public string Name { get; set; }
   }

   public class Characteristica
   {
       public Category Category { get; set; }
       public int Id { get; set; }
       public string Value { get; set; }
   }

   public class Person
   {
       public string Name { get; set; }
       public List<Characteristica> Appearance { get; set; }
   }

   class Program
   {
       static void Main(string[] args)
       {
           var persons = new List<Person>
           {
               new Person { Name = "Person A", Appearance = new List<Characteristica> { new Characteristica { Id = 22 }, new Characteristica { Id = 5 }, new Characteristica { Id = 12 } }},
               new Person { Name = "Person B", Appearance = new List<Characteristica> { new Characteristica { Id = 1 }, new Characteristica { Id = 6 }, new Characteristica { Id = 11 } }},
               new Person { Name = "Person C", Appearance = new List<Characteristica> { new Characteristica { Id = 2 }, new Characteristica { Id = 8 }, new Characteristica { Id = 13 } }},
               new Person { Name = "Person D", Appearance = new List<Characteristica> { new Characteristica { Id = 2 }, new Characteristica { Id = 5 }, new Characteristica { Id = 10 } }},
               new Person { Name = "Person E", Appearance = new List<Characteristica> { new Characteristica { Id = 1 }, new Characteristica { Id = 8 }, new Characteristica { Id = 10 } }},
               new Person { Name = "Person F", Appearance = new List<Characteristica> { new Characteristica { Id = 1 }, new Characteristica { Id = 6 }, new Characteristica { Id = 23 } }},
           };

           var listOfSearchedIds = new List<int> { 22, 23 };
           var selected = persons.Select(p => p.Appearance.Where(a => listOfSearchedIds.Contains(a.Id))).ToList();
       }
   }

現在我正在嘗試通過使用 contains 功能從我的收藏中取出“Person A”和“Person F”。但是我看不到我在這裡做錯了什麼。

有人可以闡明我做錯了什麼嗎?我嘗試了不同版本的 lambda,這是我能得到的結果,但我從我的表達中得到了所有 6 個項目。

你的方式是正確的,但你應該使用Where而不是Select

var selected = persons.Where(p => p.Appearance
               .Where(a => listOfSearchedIds.Contains(a.Id))
               .Any()).ToList();

並且您需要使用Any來檢查返回的序列 from 是否p.Appearance.Where包含任何元素。或者您可以Any直接使用並使其更短:

var selected = persons.Where(p => p.Appearance
               .Any(a => listOfSearchedIds.Contains(a.Id))
               .ToList();

嘗試以下操作:

var listOfSearchedIds = new List<int> { 22, 23 };
var selected = persons
       .Where(p => listOfSearchedIds
                       .Intersect(p.Appearance
                            .Select(a => a.Id)).Any()).ToList();

通過使用 Intersect,您可以比較兩個列表並返回兩個列表中包含的項目。Intersect 在內部使用 HashSet,因此是一種非常高效的方法,可以讓兩個人找到兩個集合的交集。如果結果列表中至少有一項,則 Any() 返回 true。

引用自:https://stackoverflow.com/questions/21919695