怎样优雅地增删查改(七):按用户查询
@
实现
定义按用户查询(IUserOrientedFilter)接口
public interface IUserOrientedFilter
{
public string EntityUserIdIdiom { get; }
Guid? UserId { get; set; }
}
- EntityUserIdIdiom:语义上的UserId,用于指定业务实体中用于描述“用户Id”字段的名称,若不指定,则默认为“UserId”
- UserId:用户Id,若为Guid.Empty,则使用当前登录用户的Id
查询实体列表Dto若实现该接口,将筛选指定 UserId 下的关联的实体。
若指定 UserId 为 Guid.Empty,则使用当前登录用户的 UserId。
ICurrentUser是Abp的一个服务,用于获取当前登录用户的信息
创建应用过滤条件方法:ApplyUserOrientedFiltered,在此实现拼接LINQ表达式,代码如下:
protected virtual IQueryable<TEntity> ApplyUserOrientedFiltered(IQueryable<TEntity> query, TGetListInput input)
{
if (input is IUserOrientedFilter)
{
var filteredInput = input as IUserOrientedFilter;
var entityUserIdIdiom = filteredInput.EntityUserIdIdiom;
if (string.IsNullOrEmpty(entityUserIdIdiom))
{
entityUserIdIdiom = "UserId";
}
if (HasProperty<TEntity>(entityUserIdIdiom))
{
var property = typeof(TEntity).GetProperty(entityUserIdIdiom);
if (filteredInput != null && filteredInput.UserId.HasValue)
{
Guid userId = default;
if (filteredInput.UserId.Value == Guid.Empty)
{
using (var scope = ServiceProvider.CreateScope())
{
var currentUser = scope.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser != null)
{
userId = currentUser.GetId();
}
}
}
else
{
userId = filteredInput.UserId.Value;
}
var parameter = Expression.Parameter(typeof(TEntity), "p");
var keyConstantExpression = Expression.Constant(userId, typeof(Guid));
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var expression = Expression.Equal(propertyAccess, keyConstantExpression);
var equalExpression = expression != null ?
Expression.Lambda<Func<TEntity, bool>>(expression, parameter)
: p => false;
query = query.Where(equalExpression);
}
}
}
return query;
}
请注意,可应用过滤的条件为:
- input需实现IUserOrientedFilter接口;
- 实体必须关联用户。
否则将原封不动返回IQueryable对象。
使用
无需在应用层中更改代码,
在GetAllAlarmInput中实现IUserOrientedFilter接口,代码如下:
public class GetAllAlarmInput : PagedAndSortedResultRequestDto, IUserOrientedFilter
{
Guid? UserId { get; set; }
public string EntityUserIdIdiom { get; }
// 或显式实现
// public string EntityUserIdIdiom => "UserId";
...
}
测试
创建一些组织架构,命名“群组”
在不同“群组”下创建一些客户(Client)
在告警管理页面中,创建一些告警,并将这些告警分配给不同的客户
告警创建完成后,进入客户管理,在右侧客户列表中点击“查看详情”
打开客户详情页面,点击“告警”标签页,可以看到该客户下的告警列表
本文来自博客园,作者:林晓lx,转载请注明原文链接:https://www.cnblogs.com/jevonsflash/p/17562446.html