我想使用ef在.net核心中编写查询。现在的问题是,我在参数中获取了属性名称,我想对该属性设置条件,即
public IQueryable<MyModel> Generate(string property, IQueryable<MyModel> query)
{
query = query.Where(a => a.property.ToLower() != null);
}
MyModel:
public string Property1 { get; set; }
public string Property2 { get; set; }
public string Property3 { get; set; }
方法调用:
var query = Generate(MyModel.Property2, query);
我知道使用反射是可行的,但是会影响性能。那么有没有更好的方法呢?
答案 0 :(得分:3)
您可以使用Func<MyModel, string>
作为参数吗?
public IQueryable<MyModel> Generate(Func<MyModel, string> propertySelector, IQueryable<MyModel> query)
{
query = query.Where(a => propertySelctor(a).ToLower() != null);
}
并像这样使用:
var query = Generate(m => m.Property2, query);
答案 1 :(得分:3)
编辑:
您可以为IQueryable实现通用的扩展方法,其中该子句是动态构建的:
public static class QueryExtensions
{
public static IQueryable<TModel> WhereNotNull<TModel>(this IQueryable<TModel> query, string propertyName)
{
var parameter = Expression.Parameter(typeof(TModel), "x");
var body = Expression.PropertyOrField(parameter, propertyName);
var comparison = Expression.NotEqual(body, Expression.Constant(null, typeof(object)));
var lambda = Expression.Lambda<Func<TModel, bool>>(comparison, parameter);
return query.Where(lambda);
}
}
这样称呼:
query = query.WhereNotNull(nameof(MyModel.Property1));
或
query = query.WhereNotNull("Property1");
要求对字符串进行空值或空格检查后,编辑:
在字符串属性上调用string.IsNullOrWhiteSpace()
的示例:
public static IQueryable<TModel> WhereNotNull<TModel>(this IQueryable<TModel> query, string propertyName)
{
var parameter = Expression.Parameter(typeof(TModel), "x");
var body = Expression.PropertyOrField(parameter, propertyName);
Expression<Func<TModel, bool>> lambda = null;
if (body.Type == typeof(string))
{
var methodCall = Expression.Call(typeof(string), nameof(string.IsNullOrWhiteSpace), null, body);
var nullOrWhiteSpaceComparison = Expression.Not(methodCall);
lambda = Expression.Lambda<Func<TModel, bool>>(nullOrWhiteSpaceComparison, parameter);
}
else
{
var nullComparison = Expression.NotEqual(body, Expression.Constant(null, typeof(object)));
lambda = Expression.Lambda<Func<TModel, bool>>(nullComparison, parameter);
}
return query.Where(lambda);
}
如果(在其他上下文中)要组合多个表达式,则可以使用Expression.And(Expression left, Expression right)
或Expression.Or(Expression left, Expression right)
。左右传递一元/二进制表达式作为参数。
答案 2 :(得分:0)
您可以这样做:
public IQueryable<TModel> Generate<TModel, TProperty>(Func<TModel, TProperty> propertyFunc, IQueryable<TModel> query)
{
return query.Where(a => propertyFunc(a) != null);
}
这将是比Dmitry更灵活的解决方案。
答案 3 :(得分:0)
Screen1