你是否想要类似这样的东西?
static List<Func<TEntity, TCriteria, bool>> GetCriteriaFunctions<TEntity, TCriteria>()
{
var criteriaFunctions = new List<Func<TEntity, TCriteria, bool>>();
var criteriaProperties = typeof(TCriteria)
.GetProperties()
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>));
foreach (var property in criteriaProperties)
{
var entityParameterExpression = Expression.Parameter(typeof(TEntity));
var criteriaParameterExpression = Expression.Parameter(typeof(TCriteria));
var criteriaPropertyExpression = Expression.Property(criteriaParameterExpression, property);
var testingForEqualityExpression = Expression.Equal(
Expression.Convert(criteriaPropertyExpression, property.PropertyType.GetGenericArguments()[0]),
Expression.Property(entityParameterExpression, property.Name));
var body = Expression.Condition(
Expression.Equal(criteriaPropertyExpression, Expression.Constant(null)),
Expression.Constant(true),
testingForEqualityExpression);
var criteriaFunction = Expression.Lambda<Func<TEntity, TCriteria, bool>>(body, entityParameterExpression, criteriaParameterExpression).Compile();
criteriaFunctions.Add(criteriaFunction);
}
return criteriaFunctions;
}
示例实体和示例条件:
class CustomerCriteria
{
public int? Age { get; set; }
public bool? IsNew { get; set; }
}
class Customer
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsNew { get; set; }
}
使用方法:
var criteriaFunctions = GetCriteriaFunctions<Customer, CustomerCriteria>();
var customer1 = new Customer { Name = "John", Age = 35, IsNew = false };
var customer2 = new Customer { Name = "Mary", Age = 27, IsNew = true };
var criteria1 = new CustomerCriteria { Age = 35 };
var criteria2 = new CustomerCriteria { IsNew = true };
Console.WriteLine("Is match: {0}", criteriaFunctions.All(f => f(customer1, criteria1)));
Console.WriteLine("Is match: {0}", criteriaFunctions.All(f => f(customer2, criteria1)));
Console.WriteLine("Is match: {0}", criteriaFunctions.All(f => f(customer1, criteria2)));
Console.WriteLine("Is match: {0}", criteriaFunctions.All(f => f(customer2, criteria2)));
与使用动态代码不同,此代码使用强类型成员访问,因此您可以缓存每个“实体-条件”对的条件列表,并更快地测试匹配实例。
{}
也会防止将 lambda 用作表达式(根据我的理解,这大概是 OP 尝试做的),但允许创建具有多个语句的委托。 - Alexei Levenkov