每个不为 null 的参数对象 属性,作为条件添加到表达式谓词
every Parameter object property that is not null, to be added to expression predicate as a condition
我正在寻找一种基于方法参数动态构建表达式的方法。
这是我的服务方法的代码片段,我想在其中构建谓词表达式。
public async Task<Account> GetCustomerAccountsAsync(Parameters params)
{
var items = await _unitOfWork.Accounts.GetWhereAsync(a => a.CustomerId == params.CustomerId && ... );
...
}
GetWhereAsync 是通用存储库中的一种方法,如下所示:
public async Task<IEnumerable<TEntity>> GetWhereAsync(Expression<Func<TEntity, bool>> predicate)
{
return await Context.Set<TEntity>().Where(predicate).ToListAsync();
}
和参数 class:
public class Parameters
{
public string CustomerId { get; set; }
public string AccountId { get; set; }
public string ProductId { get; set; }
public string CurrencyId { get; set; }
}
我想实现的是,每个 Parameter 对象 属性 不是 null,
作为条件添加到表达式谓词。
例如,如果 CustomerId 和 AccountId 有一些值,我想动态构建谓词表达式
将具有与以下谓词相同的功能:
var items = await _unitOfWork.Accounts.GetWhereAsync(a => a.CustomerId == params.CustomerId && a.AccountId == params.AccountId);
感谢任何帮助。
您不需要使用表达式在此处动态构建某些内容。你可以这样做:
_unitOfWork.Accounts.Where(a =>
(params.CustomerId == null || a.CustomerId == params.CustomerId) &&
(params.AccountId == null || a.AccountId == params.AccountId) &&
(params.ProductId == null || a.ProductId == params.ProductId) &&
(params.CurrencyId == null || a.CurrencyId == params.CurrencyId)
);
这就是我之前对具有多个可选搜索参数的搜索表单进行查询的方式。
我目前经常使用表达式,所以我想我可以帮助你。
我刚刚为您构建了自定义代码。
该代码接受您将属性添加到过滤后的 class(帐户),而无需更改过滤器构建代码。
代码过滤字符串属性并使用它来创建谓词。
public Func<Account, bool> GetPredicate(Parameters parameters)
{
var stringProperties = typeof(Parameters)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.PropertyType == typeof(string));
var parameterExpression = Expression.Parameter(typeof(Account));
var notNullPropertyNameToValue = new Dictionary<string, string>();
BinaryExpression conditionExpression = null;
foreach (var stringProperty in stringProperties)
{
var propertyValue = (string)stringProperty.GetValue(parameters);
if (propertyValue != null)
{
var propertyAccessExpression = Expression.PropertyOrField(parameterExpression, stringProperty.Name);
var propertyValueExpression = Expression.Constant(propertyValue, typeof(string));
var propertyTestExpression = Expression.Equal(propertyAccessExpression, propertyValueExpression);
if (conditionExpression == null)
{
conditionExpression = propertyTestExpression;
}
else
{
conditionExpression = Expression.And(conditionExpression, propertyTestExpression);
}
}
}
//Just return a function that includes all members if no parameter is defined.
if (conditionExpression == null)
{
return (x) => true;
}
var lambdaExpression = Expression.Lambda<Func<Account, bool>>(conditionExpression, parameterExpression);
return lambdaExpression.Compile();
}
它 returns 一个类型化的谓词,您可以在 Linq 中使用,例如。
看这个例子:
void Main()
{
var customers = new List<Account>()
{
new Account()
{
CustomerId = "1",
},
new Account()
{
CustomerId = "2",
}
};
var predicate = GetPredicate(new Parameters() { CustomerId = "1" });
customers.Where(predicate);
}
如果需要任何帮助,请随时提出!
我正在寻找一种基于方法参数动态构建表达式的方法。
这是我的服务方法的代码片段,我想在其中构建谓词表达式。
public async Task<Account> GetCustomerAccountsAsync(Parameters params)
{
var items = await _unitOfWork.Accounts.GetWhereAsync(a => a.CustomerId == params.CustomerId && ... );
...
}
GetWhereAsync 是通用存储库中的一种方法,如下所示:
public async Task<IEnumerable<TEntity>> GetWhereAsync(Expression<Func<TEntity, bool>> predicate)
{
return await Context.Set<TEntity>().Where(predicate).ToListAsync();
}
和参数 class:
public class Parameters
{
public string CustomerId { get; set; }
public string AccountId { get; set; }
public string ProductId { get; set; }
public string CurrencyId { get; set; }
}
我想实现的是,每个 Parameter 对象 属性 不是 null, 作为条件添加到表达式谓词。
例如,如果 CustomerId 和 AccountId 有一些值,我想动态构建谓词表达式 将具有与以下谓词相同的功能:
var items = await _unitOfWork.Accounts.GetWhereAsync(a => a.CustomerId == params.CustomerId && a.AccountId == params.AccountId);
感谢任何帮助。
您不需要使用表达式在此处动态构建某些内容。你可以这样做:
_unitOfWork.Accounts.Where(a =>
(params.CustomerId == null || a.CustomerId == params.CustomerId) &&
(params.AccountId == null || a.AccountId == params.AccountId) &&
(params.ProductId == null || a.ProductId == params.ProductId) &&
(params.CurrencyId == null || a.CurrencyId == params.CurrencyId)
);
这就是我之前对具有多个可选搜索参数的搜索表单进行查询的方式。
我目前经常使用表达式,所以我想我可以帮助你。
我刚刚为您构建了自定义代码。
该代码接受您将属性添加到过滤后的 class(帐户),而无需更改过滤器构建代码。
代码过滤字符串属性并使用它来创建谓词。
public Func<Account, bool> GetPredicate(Parameters parameters)
{
var stringProperties = typeof(Parameters)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.PropertyType == typeof(string));
var parameterExpression = Expression.Parameter(typeof(Account));
var notNullPropertyNameToValue = new Dictionary<string, string>();
BinaryExpression conditionExpression = null;
foreach (var stringProperty in stringProperties)
{
var propertyValue = (string)stringProperty.GetValue(parameters);
if (propertyValue != null)
{
var propertyAccessExpression = Expression.PropertyOrField(parameterExpression, stringProperty.Name);
var propertyValueExpression = Expression.Constant(propertyValue, typeof(string));
var propertyTestExpression = Expression.Equal(propertyAccessExpression, propertyValueExpression);
if (conditionExpression == null)
{
conditionExpression = propertyTestExpression;
}
else
{
conditionExpression = Expression.And(conditionExpression, propertyTestExpression);
}
}
}
//Just return a function that includes all members if no parameter is defined.
if (conditionExpression == null)
{
return (x) => true;
}
var lambdaExpression = Expression.Lambda<Func<Account, bool>>(conditionExpression, parameterExpression);
return lambdaExpression.Compile();
}
它 returns 一个类型化的谓词,您可以在 Linq 中使用,例如。
看这个例子:
void Main()
{
var customers = new List<Account>()
{
new Account()
{
CustomerId = "1",
},
new Account()
{
CustomerId = "2",
}
};
var predicate = GetPredicate(new Parameters() { CustomerId = "1" });
customers.Where(predicate);
}
如果需要任何帮助,请随时提出!