前言

  因为公司项目都是基于abp这套框架来实现功能,最近项目在调整所以我们想自己实现Module-Zero相应的功能,毕竟Module-Zero 是收费的(你懂的)今天就是实现类似审计(IHasCreationTime等)自动添加创建人,创建时间功能(子帐号概念)

思路

  1. 首先想到的是重写abp关于仓储的新增方法,代码确实很多,自身又对abp的源码没有太多的研究,放弃

  2. 每次实例化实体的时候手动给所属帐号Id手动赋值,麻烦,放弃

  3. 参考abp关于IHasCreationTime审计功能自动添加创建用户Id的思路,在继承AbpDbContext(数据上下文)中类中重写AbpDbContext定义的ObjectStateManager_ObjectStateManagerChanged这个方法。然后再声明一个受保护的SetChildAcountProperties方法用户给自账号相应字段赋值。

问题

  1. 本来想直接在XXXXXXDbContext:AbpDbContext类中声明一个基于IAbpsession扩展的Abpsession属性的,结果发现还不能这样写,关于拓展abpsession的文章请看连接博客园【圣杰】的ABP入门系列(10)——扩展AbpSession,后面采用了其他方式进行获取相应的值,下面的代码中会说明。请教各位大神为何在XXXXXXDbContext不能像下面这样获取拓展之后的AbpSession值

    public new IAbpSessionExtensions AbpSession { get; set; } 

     

  2. 本身我们子帐号就是获取abpsession的UserId,我就想能不能在获取了abpsession.UserId之后在数据上下文中使用Users.Find(AbpSession.UserId)方法来查找我需要的其他字段,发现可以但是引发了一个其他地方的问题代码如下,提示“未将对象设置到引用的错误”
    _xxxxxxRepository.Insert(model);

实现

  • 重写XXXXXXDbContext:AbpDbContext类中的ObjectStateManager_ObjectStateManagerChanged
 1 protected override void ObjectStateManager_ObjectStateManagerChanged(object sender, CollectionChangeEventArgs e)
 2         {
 3             var contextAdapter = (IObjectContextAdapter)this;
 4             if (e.Action != CollectionChangeAction.Add)
 5             {
 6                 return;
 7             }
 8 
 9             var entry = contextAdapter.ObjectContext.ObjectStateManager.GetObjectStateEntry(e.Element);
10             switch (entry.State)
11             {
12                 case EntityState.Added:
13                     CheckAndSetId(entry.Entity);
14                     CheckAndSetMustHaveTenantIdProperty(entry.Entity);
15                     SetCreationAuditProperties(entry.Entity, GetAuditUserId());
16                     SetChildAcountProperties(entry.Entity);
17                     break;
18             }
19         }
View Code

相关文章: