我基本上是在尝试构造一个查询,但我不知道为什么 Microsoft 在 Entity Framework 和 LINQ 中让这变得如此困难。我有各种参数字符串。因此,如果您看到一个变量,请假设它是从某处传入的字符串。
users = this.entities.tableUsers
.Where(searchfield+" LIKE %@0%", search)
.OrderBy(x => x.GetType().GetProperty(order_by).GetValue(x, null).ToString())
.Skip(Convert.ToInt32(limit_begin))
.Take(Convert.ToInt32(limit_end))
.ToList();
我的问题是在 LINQ 的“Where()”函数中放置什么。
我想搜索一个包含字符串“searchfield”的字段,以获取值 .contains()“search”。
不确定为什么 Visual Studio 不让我轻松地做到这一点。
我也试过这个,不走运:
.Where(x => x.GetType().GetProperty(searchfield).GetValue(x, null).ToList().Contains(search))
注意:我不想安装任何新的库,这对于现代语言来说应该非常容易和简单。我不介意查询是否返回所有行,我在使用 .Contains() 之后搜索它。
最佳答案
这不是微不足道的,但我相信这是可以做到的。以下未测试。代码借自here .
像这样在某处创建一个辅助方法
public static Expression<Func<T, bool>> GetContainsExpression<T>(string propertyName, string containsValue)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
public static Expression<Func<T, TKey>> GetPropertyExpression<T, TKey>(string propertyName)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var exp = Expression.Property(parameterExp, propertyName);
return Expression.Lambda<Func<T, TKey>>(exp, parameterExp);
}
像这样使用
users = this.entities.tableUsers
.Where(GetContainsExpression<User>(searchfield, search))
.OrderBy(GetPropertyExpression<User, string>(searchfield))
...
更新
作为替代方案,您可以创建扩展方法来提供更简洁的语法。在某处的静态类中创建以下方法:
public static IQueryable<T> WhereStringContains<T>(this IQueryable<T> query, string propertyName, string contains)
{
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(contains, typeof(string));
var containsExpression = Expression.Call(propertyExpression, method, someValue);
return query.Where(Expression.Lambda<Func<T, bool>>(containsExpression, parameter));
}
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
{
var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda(propertyExpression, new[] { parameter });
return typeof(Queryable).GetMethods()
.Where(m => m.Name == "OrderBy" && m.GetParameters().Length == 2)
.Single()
.MakeGenericMethod(new[] { typeof(T), propertyType })
.Invoke(null, new object[] { query, lambda }) as IOrderedQueryable<T>;
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
{
var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda(propertyExpression, new[] { parameter });
return typeof(Queryable).GetMethods()
.Where(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2)
.Single()
.MakeGenericMethod(new[] { typeof(T), propertyType })
.Invoke(null, new object[] { query, lambda }) as IOrderedQueryable<T>;
}
然后你可以这样称呼他们:
var users = this.entities.tableUsers.WhereStringContains(searchField, search)
.OrderBy(searchField);
关于c# - 使用动态属性搜索 LINQ 中的 Where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11994176/