下面的代码片段在不同的字段中重复出现:
if (filters.NameIsLike)
query = query.Where (x => EF.Functions.Like (x.Name, $"%{filters.Name}%"));
else
query = query.Where (x => x.Name.ToLower () == filters.Name.ToLower ());
我如何创建一个扩展方法来概括代码段的功能?
类似于:
public static IQueryable<T> EqualsOrLike (this IQueryable<T> query, ??? field, bool isLike, string filter)
{
if (isLike)
return query.Where (x => EF.Functions.Like (field.ToLower (), $"%{filter.ToLower ()}%"));
else
return query.Where (x => field.ToLower () == filter.ToLower ());
}
提前感谢!
更新日期:
以下是初始代码段的使用方式(作为示例):
在本例中,类是Company,但也可能是其他的东西......因此,我不知道类或字段。注解解释了我将如何使用EqualsOrLike
函数:
protected override IQueryable<Company> _QueryAsync (IQueryable<Company> query, QueryFilterBase filter)
{
CompanyQueryFilter filters = (CompanyQueryFilter)filter;
if (!string.IsNullOrEmpty (filters.Name))
{
if (filters.NameIsLike)
query = query.Where (x => EF.Functions.Like (x.Name.ToLower (), $"%{filters.Name.ToLower ()}%"));
else
query = query.Where (x => x.Name.ToLower () == filters.Name.ToLower ());
//query = EqualsOrLike (query, x => x.Name, filters.NameIsLike, filters.Name);
}
if (!string.IsNullOrEmpty (filters.AtecoCode))
query = query.Where (x => EF.Functions.Like (x.AtecoCode, $"%{filters.AtecoCode}%"));
if (!string.IsNullOrEmpty (filters.VatNumber))
{
if (filters.VatNumberIsLike)
query = query.Where (x => EF.Functions.Like (x.VatNumber, $"%{filters.VatNumber}%"));
else
query = query.Where (x => x.VatNumber.ToLower () == filters.VatNumber.ToLower ());
//query = EqualsOrLike (query, x => x.VatNumber, filters.VatNumberIsLike, filters.VatNumber);
}
return query;
}
2条答案
按热度按时间qij5mzcb1#
由于您不知道要比较的属性,因此需要手动建立运算式。
第一步,我发现了解C#如何使用反编译器编译表达式是很有用的;
稍微清理一下就会给予以下结果:
您现在可以调整它来替换传入的类型和属性名。注意,您需要保留捕获的lambda,以便EF将此值绑定为参数。否则EF和Sql server每次都需要重新编译查询。
选项2,您可以使用
ExpressionVisitor
来调整模板表达式。例如,如果您既有要比较的字段的表达式,也有要执行的比较的表达式。您可以将一个表达式的参数替换为另一个表达式的主体。给出一个完整的解决方案,看起来像这样:
由于这种类型的替换是一种相当常见的操作,因此您可以重用EF Core的
ReplacingExpressionVisitor
,而不是编写自己的ReplacingExpressionVisitor
。b1uwtaje2#
可以使用
Func
从结果中选择字段:你可以这样称呼它: