LINQ to SQL复杂查询

时间:2013-08-13 15:06:55

标签: c# sql linq linq-to-sql

我有以下对象

public Cell {
    public string CategoryId {get; set;}
    public DateTime FromTime {get; set}
    public DateTime ToTime {get; set}
}

我有一个名为Item的数据库表,如下所示:

Item

-------------------------
CategoryId    LastUpdated

现在在代码中我有一个包含多个Cell的Cell List<Cell> ToBeFetchedFromDB列表,假设列表包含FooBar,我想动态构建这样的查询BY INTERATING THROUGH THE COLLECTION ToBeFetchedFromDB WITHIN MY LINQ TO SQL QUERY而不是静态构建查询:

from x in Item
where x.CategoryId == Foo.CategoryId && Foo.FromTime < x.LastUpdated < Foo.ToTime
      || x.CategoryId == Bar.CategoryId && Bar.FromTime < x.LastUpdated < Bar.ToTime
select x

我一直在尝试,但无法弄明白:(

谢谢你们!

1 个答案:

答案 0 :(得分:4)

使用PredicateBuilder,您可以使用foreach浏览列表中的每个项目,并为您的过滤器添加新选项:

var filter = PredicateBuilder.False<Item>();

foreach (var cell in ToBeFetchedFromDB)
{
    filter = PredicateBuilder.Or(filter, item => 
        item.CategoryId == cell.CategoryId &&
        cell.FromTime < item.LastUpdated &&
        item.LastUpdated < cell.ToTime);
}

var query = Item.Where(filter);

链接中的PredicateBuilder副本:

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T>() { return f => true; }
    public static Expression<Func<T, bool>> False<T>() { return f => false; }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                        Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
                (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
                (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
    }
}