【问题标题】:Filter Linq Child Collection by another List/Array通过另一个列表/数组过滤 Linq 子集合
【发布时间】:2016-09-24 01:23:00
【问题描述】:

当我尝试根据一个简单的值过滤子集合时,我可以通过执行以下操作轻松完成:

db.Table.Where(a => a.SubTable.Any(b => b.SubTableId == 1));

但是当我尝试根据与其对应的值列表过滤同一个子集合时,我总是遇到错误。

List<long> listOfIDs = new List<long> { 1, 2, 3 };
db.Table.Where(a => listOfIDs.Any(a.SubTable.Select(b => b.SubTableId));

我搜索了很多如何做到这一点,但我仍在启动 EF。我得到的错误是无法从 System.Collections.Generic 转换为 Func。

任何人冷请帮我告诉我我做错了什么?我只想使用数组、列表、任何东西来过滤集合...

问候, 鲁本斯

【问题讨论】:

    标签: entity-framework linq filter


    【解决方案1】:

    你可以试试如下图。

    db.Table.Where(a => a.SubTable.Any(x=> listOfIDs.Contains(x.SubTableId)));
    

    【讨论】:

    • 非常感谢@Sampath 的帮助。在我的具体情况下,我必须做一些改变 db.Table.Where(a => a.SubTable.Any(b => listOfIds.Contains(b.SubTableId)));
    【解决方案2】:

    你几乎拥有它。您需要反转嵌套谓词中的逻辑来执行您正在搜索的集合,然后将 lambda 延续变量公开给它。我举了一个更复杂的例子,假设你有一个其他复杂对象的集合,并且你想找到这些对象及其父对象的属性:

    public class POC
    {
      public int Id { get; set; }
      public string Desc { get; set; }
      public List<Order> Orders { get; set; }
    }
    
    public class Order
    {
      public int Id { get; set; }
      public string Desc { get; set; }
    }
    
    static List<Order> GetOrders(int numberOfOrders)
    {
      var orders = new List<Order>();
    
      for (int i = 1; i <= numberOfOrders; i++)
      {
        orders.Add(new Order { Id = i, Desc = $"{i} Order" });
      }
    
      return orders;
    }
    
    static List<POC> GetPOCOsAndOrders()
    {
      return new List<POC>
      {
          new POC { Id = 1, Desc = "John", Orders = GetOrders(1)},
          new POC { Id = 2, Desc = "Jane", Orders = GetOrders(2) },
          new POC { Id = 3, Desc = "Joey" , Orders = GetOrders(3)}
      };
    }
    
    
    static void Main(string[] args)
    {
      var orders = new List<int> { 2, 3 };
      var items = GetPOCOsAndOrders();
    
      var peopleAndOrdersWhereOrderNumberIsGreaterThanTwo = items.Where(x => x.Orders.Any(y => orders.Contains(y.Id)));
    
      //I should only get the last two people out of three and their orders
      peopleAndOrdersWhereOrderNumberIsGreaterThanTwo.ToList().ForEach(x => Console.WriteLine($"{x.Id} {x.Desc} {x.Orders.Count}"));
    
      Console.ReadLine();
    }
    

    【讨论】:

    • 你不知道我为此搜索了多少,说真的。非常感谢您帮助我,特别是为了更好地理解正确的逻辑。我不得不反过来想,这开始几乎是不可能的。再次感谢@djangojazz
    • 没问题,愉快的编码。
    【解决方案3】:

    试试这个:

        var ResultList=(
          from elemID in listOfIDs 
          from elemA in db.Table.Where(elemA => elemA.SubTable.Contains(elemID)).DefaultIfEmpty() 
         where elemA !=null
         select elemA).ToList(); 
    

    【讨论】:

      【解决方案4】:

      尝试从子表开始:

      var results = from s in SubTable
                    join id in listOfIDs on s.SubTableID equals id.ID
                    select s.Table; 
      

      或者如果你喜欢

      var results = subTables.Where(a => listOfIDs.Contains(a.SubTableID))
                             .Select(s => s.Table);
      

      最后,如果您无权访问 SubTable 表

       var results = tables.Select(t => t.SubTable)
                           .Where(a => listOfIDs.Contains(a.SubTableID))
                           .Select(s => s.Table);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-29
        相关资源
        最近更新 更多