IQIeryable适用于多列表比较的地方

时间:2014-06-04 15:32:33

标签: c# linq linq-to-sql

我有一个基本的IQueryable,

private static IQueryable<TestObject> GetFilteredQuery(Guid componentId, Guid productId)
    {
      IQueryable<TestObject> query = from t in ModelQuery.Query<TestObject>()
                                     where t.ComponentId == componentId && t.ProductId == productId
                                     select t;
      return query;
    }

如果我必须比较单个componentId和productId,这是微不足道的。

我的问题是,当我有一个价值对列表时,我该如何处理,

  

Guid [] componentIds,Guid [] productIds

其中,它的keyValue对的种类。

之类的,

 private static IQueryable<TestObject> GetFilteredQuery(Guid[] componentIds, Guid[] productIds)
    {
      IQueryable<TestObject> query = from t in ModelQuery.Query<TestObject>()
                                     where (t.ComponentId must be present in componentIds[] && t.ProductId must be present in productIds)
                                     select t;
      return query;
    }

2 个答案:

答案 0 :(得分:1)

使用Contains

 private static IQueryable<TestObject> GetFilteredQuery(Guid[] componentIds, Guid[] productIds)
    {
      IQueryable<TestObject> query = 
         from t in ModelQuery.Query<TestObject>()
         where (componentIds.Contains(t.ComponentId) 
                && productIds.Contains(t.ProductId))
         select t;
      return query;
    }

修改

AFAIK没有办法Linq2Sql将一系列Guid元组映射到本机Sql(你可能需要一个@Table参数)

所以这是一种方法,即运行与上面相同的查询,但在2个过滤器列表上使用OR。希望Sql能够在数据库级别过滤掉大量数据。

然后需要实现结果(candidates),然后在内存中针对组件和产品对进行过滤。我通过将2个guid数组压缩在一起来做到这一点(假设长度相似 - 可能你想将数组重新编码为Pairs数组以更明确地表达意图?)

private static IQueryable<TestObject> GetFilteredQuery(Guid[] componentIds, 
                                                       Guid[] productIds)
{
    var candidates = ModelQuery
         .Query<TestObject>()
         .Where(componentIds.Contains(
                         t.ComponentId) || productIds.Contains(t.ProductId))
         .ToList();// Need to materialize

    var guidPairs = componentIds.Zip(productIds, 
          (c, p) => new {ComponentId = c, ProductId = p});

    return candidates
      .Join(guidPairs, 
            c => new {ComponentId = c.ComponentId, ProductId = c.ProductId}, 
            gp => gp, 
            (c, gp) => c)
      .AsQueryable();
}

请注意,由于已经实现了,因此生成的可查询对象不适合进一步合成。此外,如果您在点击之前可以进行额外的过滤,那将是有益的。而且我担心我实际上没有测试过这个。

答案 1 :(得分:0)

使用Contains

where componentIds.Contains(t.ComponentId) && productIds.Contains(t.ProductId)