我正在使用针对Entity Framework 4.0的SL 4,WCF RIA服务。我有一个Entity,Visit,它有一个字符串Status字段。我有一个搜索屏幕,我需要显示具有StatusA或StatusB的结果。我正在努力寻找一种方法来指定一个客户端查询,该查询指定了应该匹配的状态集合。如果我在SQL中编写我想要的内容,它将类似于:
select * from Visit where Status in ('StatusA', 'StatusB');
客户方面,将WhereAnd效果的Where方法链接起来似乎很简单:
var query = this.PqContext.GetVisitsQuery();
if (!string.IsNullOrEmpty(this.PracticeName))
{
query = query.Where(v => v.PracticeName.ToUpper().Contains(this.PracticeName.ToUpper()));
}
if (this.VisitDateAfter.HasValue)
{
query = query.Where(v => v.VisitDate > this.VisitDateAfter);
}
if (this.VisitDateBefore.HasValue)
{
query = query.Where(v => v.VisitDate < this.VisitDateBefore);
}
但是,我似乎无法找到一种直接的方式来进行WhereOr样式操作。我试过这个:
var statuses = new List<string>();
if (this.ShowStatusA)
{
statuses.Add("StatusA");
}
if (this.ShowStatusB)
{
statuses.Add("StatusB");
}
if (statuses.Any())
{
query = query.Where(BuildContainsExpression<Visit, string>(e => e.Status, statuses));
}
BuildContainsExpression的位置如下:
private static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
if (null == valueSelector)
{
throw new ArgumentNullException("valueSelector");
}
if (null == values)
{
throw new ArgumentNullException("values");
}
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
{
return e => false;
}
var equals =
values.Select(
value =>
(Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>(Expression.Or);
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
但这会引发“查询中不支持按位运算符”。例外。有线索吗?有没有另一种方法来构建一个在这里工作的表达式树,或者我是否需要将所有参数传递给服务器并在那里使用BuildContainsExpression?
非常感谢您的时间和指导。
答案 0 :(得分:1)
您可以在域名服务中创建如下的查询方法:
GetVisitsByStatus(string[] statusList) {
// create the LINQ where clause here
}
然后从客户端调用context.GetVistsByStatusQuery(string [])。
并非所有的LINQ都可以(甚至可以)通过URL公开,因此总是需要使用简单的参数,并让中间层构造LINQ表达式,最终定义查询到达后端数据存储。
希望有所帮助。