我正在使用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.
也许问题开始了,有人能帮我吗?谢谢
因为多个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);