实现
定义按用户查询(IUserOrientedFilter)接口
1 2 3 4 5 6
| 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表达式,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| 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接口,代码如下:
1 2 3 4 5 6 7 8 9 10 11
| public class GetAllAlarmInput : PagedAndSortedResultRequestDto, IUserOrientedFilter { Guid? UserId { get; set; } public string EntityUserIdIdiom { get; } // 或显式实现 // public string EntityUserIdIdiom => "UserId"; ... }
|
测试
创建一些组织架构,命名“群组”
在不同“群组”下创建一些客户(Client)
在告警管理页面中,创建一些告警,并将这些告警分配给不同的客户
告警创建完成后,进入客户管理,在右侧客户列表中点击“查看详情”
打开客户详情页面,点击“告警”标签页,可以看到该客户下的告警列表