@
- 实现
- 应用
- 测试
实现
定义按任意字段关键字查询过滤器(IKeywordOrientedFilter)接口,查询实体列表Dto若实现该接口,将筛选指定的目标字段(TargetFields)包含指定的关键字(Keyword)的实体。
public interface IKeywordOrientedFilter
{
public string Keyword { get; set; }
public string TargetFields { get; set; }
}
创建应用过滤条件方法:ApplySearchFiltered,代码如下:
protected virtual IQueryable ApplySearchFiltered(IQueryable query, TGetListInput input)
{
if (input is IKeywordOrientedFilter)
{
var filteredInput = input as IKeywordOrientedFilter;
if (filteredInput != null)
{
var targetFields = new string[] { "Name", "Title" };
if (!string.IsNullOrEmpty(filteredInput.TargetFields))
{
targetFields = filteredInput.TargetFields.Split(',');
}
return query.WhereIf(!filteredInput.Keyword.IsNullOrWhiteSpace(),
FilterByKeywordDynamic(filteredInput.Keyword, targetFields));
}
}
return query;
}
请注意,可应用过滤的条件为:
- input需实现IKeywordOrientedFilter接口,且Keyword不为空;
- 若filteredInput.TargetFields为空,则默认使用Name和Title字段进行筛选。
对于每一个TargetField,需要在实体中找到对应字段(属性)。若找到,则为此实体字段创建条件筛选的表达式,然后将这些表达式通过Or连接起来,最终返回一个包含多段关键字筛选的Lambda表达式。
创建FilterByKeywordDynamic方法,代码如下:
private Expression> FilterByKeywordDynamic(string keyword, params string[] sortColumns)
{
var parameter = Expression.Parameter(typeof(T), "p");
var propertys = sortColumns.Select(sortColumn => typeof(T).GetProperty(sortColumn));
var method = typeof(string)
.GetMethods()
.FirstOrDefault(x => x.Name == "Contains");
var keyConstantExpression = Expression.Constant(keyword, typeof(string));
Expression originalExpression = null;
foreach (var property in propertys)
{
if (property != null)
{
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var expression = Expression.Call(propertyAccess, method, keyConstantExpression);
if (originalExpression == null)
{
originalExpression = expression;
}
else
{
originalExpression = Expression.Or(originalExpression, expression);
}
}
}
var result = originalExpression != null ?
Expression.Lambda>(originalExpression, parameter)
: p => true;
return result;
}
创建默认的应用过滤规则DefaultConvention,将之前的按组织架构查询和按关键字查询的代码提取到DefaultConvention方法中,此类可派生,使用virtual关键字以便在子类中重写,代码如下:
protected virtual async Task> DefaultConvention(TGetListInput input, IQueryable query)
{
query = ApplySearchFiltered(query, input);
query = ApplyUserOrientedFiltered(query, input);
return query;
}
在CreateBriefFilteredQueryAsync和CreateFilteredQueryAsync方法中调用DefaultConvention方法,代码如下:
protected virtual async Task> CreateBriefFilteredQueryAsync(TGetListBriefInput input)
{
var query = await ReadOnlyRepository.GetQueryableAsync();
query = await DefaultConvention(input, query);
return query;
}
protected override async Task> CreateFilteredQueryAsync(TGetListInput input)
{
var query = await ReadOnlyRepository.GetQueryableAsync();
query = await DefaultConvention(input, query);
return query;
}
应用
无需在应用层中更改代码,
在GetAllAlarmInput中实现IKeywordOrientedFilter接口,代码如下:
public class GetAllAlarmInput : PagedAndSortedResultRequestDto, IKeywordOrientedFilter
{
//keyword
public string Keyword { get; set; }
public string TargetFields { get; set; }
...
}
测试
在告警管理页面建立一些告警
在筛选中输入关键字“3”,点击查询
可以看到将筛选出标题包含关键字“3”的告警
查询的报文Payload如下图:
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
上次我们说了一下 微服务的容错处理,是用的 断路器 这一次我们来一起看看 微服务的负载均衡是如何做的 负载均衡 负载均衡是什么呢? 他能够将大量的请求,根据负载均衡算法,将不同的请求分发到多台服务器上进行处理,使得所有的服务器负载都维持在一个高效稳定的状态,进…