代码之家  ›  专栏  ›  技术社区  ›  grinay

带EF核心的自定义过滤器

  •  0
  • grinay  · 技术社区  · 7 年前

    我在这里找到了一些关于这个话题的答案,但它们并没有完全涵盖我的问题。 我的目标是使实体具有用户作为所有者。

    public interface IMustHaveUser
    {
        long UserId { get; set; }
    }
    

    我在预初始化方法中的EFCoreModule中注册自定义过滤器

    public override void PreInitialize() {
     //Register custom data filters
     Configuration.UnitOfWork.RegisterFilter("MustHaveUser", true);
     //other code here...
    }
    

    定义一个属性,用于检查过滤器是否已启用

    protected virtual bool IsMustHaveUserFilterEnabled => CurrentUnitOfWorkProvider?.Current?.IsFilterEnabled("MustHaveUser") == true;
    

    并重写CreateFilterExpression方法。

     protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
        {
            var expression = base.CreateFilterExpression<TEntity>();
    
            if (typeof(IMustHaveUser).IsAssignableFrom(typeof(TEntity)))
            {
                Expression<Func<TEntity, bool>> userFilter = e => ((IMustHaveUser) e).UserId == AbpSession.UserId || (((IMustHaveUser) e).UserId == AbpSession.UserId) == IsMustHaveUserFilterEnabled;
                expression = expression == null ? userFilter : CombineExpressions(expression, userFilter);
            }
    
    
            return expression;
        }
    

    现在,当我创建实体时,我必须手动设置UserID。

    void Create(Product product, UserIdentity user){
        product.UserId = user.UserId;
        //Other business rules and insert with repository
    
    }
    

    我的问题是如何设置当前用户ID。还有其他最简单(更好)的方法吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   grinay    7 年前

    我忘了戴。找到了解决办法。基本上,我已经将IAbpSession注入到Automapper配置文件中,并在其中映射用户ID。

    public class AutoMapperProfile : AutoMapper.Profile
        {
            private IAbpSession _abpSession;
    
            public AutoMapperProfile()        {
    
                _abpSession = IocManager.Instance.Resolve<IAbpSession>();
    
    
    
                CreateMap<LicenseInput, License>()
                    .ForMember(x => x.UserId, options => options.MapFrom(src => _abpSession.UserId));
    
    
            }
        }
    
        2
  •  0
  •   grinay    7 年前

    最后我用另一种方式做了,因为这种方式使得代码对于集成测试来说很困难。 我不知道为什么文档会错过这一刻,我必须阅读github的源代码,以了解现有过滤器的工作原理,例如MustHaveTenant等。

    MyDbContext中的最终代码如下所示:

        protected override void ApplyAbpConceptsForAddedEntity(EntityEntry entry, long? userId, EntityChangeReport changeReport)
        {
            CheckAndSetMustHaveUserIdProperty(entry.Entity, userId);
            base.ApplyAbpConceptsForAddedEntity(entry, userId, changeReport);
        }
    
        private void CheckAndSetMustHaveUserIdProperty(object entryEntity, long? userId)
        {
            if (userId == null)
                return;
    
    
            if (!(entryEntity is IMustHaveUser))
            {
                return;
            }
    
            var entity = entryEntity.As<IMustHaveUser>();
    
    
            entity.UserId = userId.Value;
        }
    
    推荐文章