【发布时间】:2014-01-02 16:11:50
【问题描述】:
有什么方法可以动态选择在哪个列上运行?我不需要比较,只需要动态选择的列。
where SqlMethods.Like(s.GradeLevel, grade)
【问题讨论】:
标签: c# .net linq linq-to-sql
有什么方法可以动态选择在哪个列上运行?我不需要比较,只需要动态选择的列。
where SqlMethods.Like(s.GradeLevel, grade)
【问题讨论】:
标签: c# .net linq linq-to-sql
您可以使用表达式动态构建查询。这是我写的一个例子,可以动态选择要过滤的列。
private static Expression GetStringCompareExpression<TEntity>(Expression parameters, string method, FilterContainer filter, Type type)
{
Expression expression;
MemberExpression field = Expression.PropertyOrField(parameters, filter.field);
Expression constant = Expression.Constant(filter.value.ToLower().Trim(), type);
Expression lowercase = Expression.Call(field, "ToLower", null, null);
Expression trim = Expression.Call(lowercase, "Trim", null, null);
expression = AddNotNullExpression(field, Expression.Call(trim, method, null, constant));
return expression;
}
这个有以下作用:
这里是“AddNotNullExpression”方法:
private static Expression AddNotNullExpression(MemberExpression field, Expression expression)
{
if(field.Type.IsNullable())
{
// String mag niet null zijn
Expression nullConstant = Expression.Constant(null, field.Type);
Expression notNull = Expression.NotEqual(field, nullConstant);
expression = Expression.AndAlso(notNull, expression);
}
return expression;
}
这样称呼它:
Expression expression = GetStringCompareExpression<TEntity>(parameters, "Contains", filter, propertyInfo.PropertyType);
最后像这样返回 IQueryable:
public static IQueryable<TEntity> Where<TEntity>(this IQueryable<TEntity> query, FilterContainer filters)
{
Expression expression = GetSingleExpression<TEntity>(filters, parameters);
var lambda = Expression.Lambda<Func<TEntity, bool>>(expression, parameters);
return query.Where(lambda);
}
这并不完全是您所要求的,因为它是为了翻译来自视图中网格(位于 FilterContainer 中)的过滤器表达式而编写的,但它提供了一个关于如何自己编写“Like”的想法
【讨论】:
如果您的“动态”取决于某个条件,那么它们是的。首先在没有此条件的情况下构建您的 linq 查询。然后添加 if 语句并添加适当的条件。
var query = ....;
if (value1 = condition1) {
query = from q in query
where SqlMethods.Like(s.GradeLevel, grade);
}
if (value2 == condition2) {
query = from q in query
where SqlMethods.Like(s.Name, name);
}
查询将建立在最后一刻,而不是提前,因此您可以安全地使用这种方法。
【讨论】: