如何结合表达式

时间:2013-08-21 15:41:19

标签: c# wcf entity-framework-5

我正在使用EF并希望将WCF服务传递给过滤器功能。 如果我有一个过滤器,一切都很好,但当我尝试将一些表达式组合在一起时,我得到一个恼人的错误: 底层连接已关闭:服务器已关闭预期保持活动状态的连接。

所以这是我的Filter对象:

public class EventFilter
{
    public int CategoryId { get; set; }
    public int SubCategoryId { get; set; }
    public DateTime StartDate { get; set; }
    public int? Duration { get; set; }
    public string Address { get; set; }
}

这是过滤功能,它可以正常工作(一个过滤器):

public IQueryable<Event> GetBySearch(EventFilter search)
{
    Expression<Func<Event, bool>> where = null;

    if (search.CategoryId != 0)
    {
        where = x => x.CategoryId == search.CategoryId;
    }

    return this.Context.Events.Where(where);
}

但是如果我想将它扩展为两个过滤器,它就无法正常工作,我无法理解如何修复它。

所以,这是组合功能,我认为没问题。

private static Expression<Func<TEntity, bool>> Combine<TEntity>(Expression<Func<TEntity, bool>> a, Expression<Func<TEntity, bool>> b)
{
    var and = Expression.AndAlso(a.Body, b.Body);
    var param = Expression.Parameter(typeof(TEntity));

    return Expression.Lambda<Func<TEntity, bool>>(and, param); ;
}

这是问题过滤器功能(当两个过滤器都发生时它不起作用:

public IQueryable<Event> GetBySearch(EventFilter search)
{
    Expression<Func<Event, bool>> where = null;

    if (search.CategoryId != 0)
    {
        where = x => x.CategoryId == search.CategoryId;
    }

    if (search.SubCategoryId != 0)
    {
        where = Combine<Event>(where, x => x.SubCategoryId == search.SubCategoryId);;
    }

    return this.Context.Events.Where(where);
}

我尝试了很多种写法,我试图在结果中输入一个新对象,例如:

public IQueryable<Event> GetBySearch(EventFilter search)
{
    Expression<Func<Event, bool>> where = null;
    Expression<Func<Event, bool>> where2 = null;

    if (search.CategoryId != 0)
    {
        where = x => x.CategoryId == search.CategoryId;
    }

    if (search.SubCategoryId != 0)
    {
        where2 = x => x.SubCategoryId == search.SubCategoryId;
    }

    var result = Combine(where, where2);

    return this.Context.Events.Where(result);
}

毕竟我注意到这段代码有效:

Expression<Func<Event, bool>> where3 = (x => x.CategoryId == search.CategoryId) && (x => x.SubCategoryId == search.SubCategoryId);

虽然不是这样:

Expression<Func<Event, bool>> where3 = where && where2; //Compile time error.

也许在这里问题开始了,有人可以帮助我吗? 谢谢!!!

1 个答案:

答案 0 :(得分:2)

因为多个Where子句被AND组合在一起并且每个子句返回IQueryable<Event>,所以您可以将多个子句链接在一起,就像这样。

public IQueryable<Event> GetBySearch(EventFilter search)
{
    IQueryable<Event> events = this.Context.Events; //(I assume Events is an IQueryable<Event>)

    if (search.CategoryId != 0)
    {
        events = events.Where(x => x.CategoryId == search.CategoryId);
    }

    if (search.SubCategoryId != 0)
    {
        events = events.Where(x => x.SubCategoryId == search.SubCategoryId);
    }

    return events;
}

这实际上有效(假设两个id都不是0)

this.Context.Events.Where(x => x.CategoryId == search.CategoryId).Where(x => x.SubCategoryId == search.SubCategoryId);

相同
this.Context.Events.Where(x => x.CategoryId == search.CategoryId && x.SubCategoryId == search.SubCategoryId);