如何在实体框架中动态构造Where表达式? [英] How to construct Where Expression dynamically in Entity Framework?
问题描述
I've taken a look at this answer on how to dynamically create an OrderBy expression in Entity Framework. But I'd like to also build a dynamic Where expression. Something along the lines of this:
public IEnumerable<InventoryItem> GetAll(string filterBy, object value)
{
var results = new List<InventoryItem>();
using (var db = new InventoryDb())
{
if (QueryHelper.PropertyExists<InventoryItem>(filterBy))
{
var query = db.rri_InventoryItems.WhereByProperty(filterBy, value);
foreach(var item in query.Where(expr))
{
results.Add(ConvertItem(item));
}
}
}
return results;
}
传入属性以按过滤,并将值作为ab对象. Queryable有两种方法,其中Where都带有两个参数,所以我什至不确定哪一个是正确的.
Passing in the property to filter by and a value as ab object. Queryable has two methods for Where that both take two parameters, so I am not even sure which is the proper one.
在这一点上,我迷路了.我不确定如何重构原始的 OrderByProerty 方法以提供 WhereByProperty .我知道我这里完全是错误的.我不确定该怎么办.
And it's at this point I get a little more lost. I'm not sure how to refactor the original OrderByProerty method to provide a WhereByProperty. I know what I have here is completely wrong. I'm not sure what to do with it.
理想情况下,我想通过提供一组对象来进一步扩展此范围,这些对象可用于使用和和或运算符来构建查询.
Ideally, I'd want to extend this even more by providing a collection of objects that could be used to build a query with ands and or operators.
推荐答案
Queryable有两种方法,它们都使用两个参数,所以我什至不确定哪一个是正确的.
Queryable has two methods for Where that both take two parameters, so I am not even sure which is the proper one.
您需要一个接收Expression<Func<T, bool>> predicate
的人.
You need the one that receives Expression<Func<T, bool>> predicate
.
在这里,您可以动态地构建类似于(T item) => item.Property == value
的谓词:
Here is how you can build dynamically a predicate similar to (T item) => item.Property == value
:
public static partial class QueryableExtensions
{
public static IQueryable<T> WhereEquals<T>(this IQueryable<T> source, string member, object value)
{
var item = Expression.Parameter(typeof(T), "item");
var memberValue = member.Split('.').Aggregate((Expression)item, Expression.PropertyOrField);
var memberType = memberValue.Type;
if (value != null && value.GetType() != memberType)
value = Convert.ChangeType(value, memberType);
var condition = Expression.Equal(memberValue, Expression.Constant(value, memberType));
var predicate = Expression.Lambda<Func<T, bool>>(condition, item);
return source.Where(predicate);
}
}
我试图以这种方式编写它,以便您可以逐步执行代码以了解它的作用.可能需要解释的唯一一行是:
I've tried to write it in such a way so you can step over the code in order to understand what it does. The only line that might need some explanation is:
var memberValue = member.Split('.').Aggregate((Expression)item, Expression.PropertyOrField);
这是处理诸如obj.Prop1.Prop2
等嵌套属性的简单方法.如果不需要这种功能,则可以简单地使用此功能:
This is a simple way of handling nested properties like obj.Prop1.Prop2
etc. If you don't need such capability, you can simply use this instead:
var memberValue = Expression.PropertyOrField(item, member);
这篇关于如何在实体框架中动态构造Where表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!