[英]Dynamic expression for filter IQueryable
I have a situation where I have just the property name (string) and the value by which desire filter. 我遇到的情况是我只有属性名称(字符串)和所需过滤器的值。 I need to filter the list to return true
if any name repeated. 如果需要重复任何名称,我需要过滤列表以返回true
。
Remembering that the filter should exclude it yourself. 记住过滤器应该自己排除它。 With expression like: p => p.Id != currentId
使用如下表达式: p => p.Id != currentId
As the property is a string, I decided to create a Dynamic Expression to solve this problem. 由于该属性是字符串,因此我决定创建一个动态表达式来解决此问题。
[TestMethod]
public void TestingExpression()
{
// Arrange
var fix = new Fixture();
var list = fix.Build<User>()
.With(p => p.Name)
.OmitAutoProperties()
.CreateMany(20).AsQueryable(); // Create IQueryable<User> with 20 users
// Act
var currentId = 2;
var uniquePropName = "Name";
var uniqueValue = "{NotFoundValue}";
// Expression: p => p.Id != currentId
ParameterExpression pId = Expression.Parameter(typeof(int), "Id");
ConstantExpression cId = Expression.Constant(currentId, typeof(int));
BinaryExpression notCurrent = Expression.NotEqual(pId, cId);
Expression<Func<int, bool>> NotCurrentExpr =
Expression.Lambda<Func<int, bool>>(
notCurrent,
new ParameterExpression[] { pId });
// Expression: p.{uniquePropName} == {uniqueValue}
ParameterExpression pUnique = Expression.Parameter(typeof(string), uniquePropName);
ConstantExpression cUnique = Expression.Constant(uniqueValue, typeof(string));
BinaryExpression checkUnique = Expression.Equal(pUnique, cUnique);
Expression<Func<string, bool>> CheckUniqueExp =
Expression.Lambda<Func<string, bool>>(
checkUnique,
new ParameterExpression[] { pUnique });
var exp = Expression.And(NotCurrentExpr, CheckUniqueExp);
// Asset
list.Provider.CreateQuery<User>(exp).ToList()
.Should().HaveCount(19);
}
The goal is to create a dynamic expression as: query.Any(p => p.Id != id && p.{Dynamic} == nome);
目标是创建一个动态表达式,如下所示: query.Any(p => p.Id != id && p.{Dynamic} == nome);
But I do not know how to continue .. 但是我不知道如何继续..
Thanks 谢谢
A nice tutorial can be found here . 一个很好的教程可以在这里找到。
You seem to be confusing the parameters and properties. 您似乎在混淆参数和属性。 Here is a further example: 这是另一个示例:
//user => user.SomeProperty == someValue
//the parameter of the predicate, a User object in your case
ParameterExpression parameter = Expression.Parameter(typeof(User), "user");
//the property of the user object to use in expression
Expression property = Expression.Property(parameter, myPropertyNameString);
//the value to compare to the user property
Expression val = Expression.Constant(myValueToCompare);
//the binary expression using the above expressions
BinaryExpression expEquals = Expression.Equal(property, val);
//create the Expression<Func<T, Boolean>>
var predicate = Expression.Lambda<Func<User, Boolean>>(expEquals, parameter);
Furthermore in your code you try and create two lambdas whereas your aim is to produce 此外,在您的代码中,您尝试创建两个lambda,而您的目标是生成
p => p.Id != id && p.{Dynamic} == nome
This is a single lambda that takes 1 parameter with the body consisting of two binary expressions and a conditional AND
operator producing a Boolean
result. 这是一个带1个参数的lambda,其主体由两个二进制表达式和一个条件AND
运算符组成,该运算符产生Boolean
结果。 You should instead use Expression.AndAlso()
to apply the &&
operator to your binary expressions and then use Expression.Lambda<Func<User, Boolean>>()
to get your final lambda expression. 您应该改为使用Expression.AndAlso()
将&&
运算符应用于二进制表达式,然后使用Expression.Lambda<Func<User, Boolean>>()
获得最终的lambda表达式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.