欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

DDD Code First 迁移数据实现EF CORE的软删除,值对象迁移配置

程序员文章站 2022-06-25 08:16:15
感谢Jeffcky大佬的博客: EntityFramework Core 2.0全局过滤 (HasQueryFilter) https://www.cnblogs.com/CreateMyself/p/8491058.html 什么是值对象 没有唯一的标识,固定不变的,表示一个具体的概念,用来描述一 ......

感谢jeffcky大佬的博客:

entityframework core 2.0全局过滤 (hasqueryfilter) https://www.cnblogs.com/createmyself/p/8491058.html

什么是值对象


没有唯一的标识,固定不变的,表示一个具体的概念,用来描述一个东西的特征,代表是什么,使用时直接添加或替换,值对象在迁移时,会以字段的形式迁移到数据库中

软删除

定义删除的接口

         public interface isoftdelete
         {
            bool isdeleted { get; set; }
         }
     

创建模型实现isoftdelete接口

       public class userinfo : iaggregationroot, isoftdelete
        {       
          public guid id { get; set; }
          public string username { get; private set; }
          public string userpassword { get; private set; }
          public string userphone { get; private set; }
          public address address { get; private set; }
          public bool isdeleted { get; set; }
        }
        [owned]
        public class address:ivalueobject
        { 
          public string province { get;private set; }
          public string city { get; private set; }
          public string county { get; private set; }
          public string addressdetails { get; private set; }    
        }
     

lamda的扩展以及code first 迁移配置

    protected override void onmodelcreating(modelbuilder modelbuilder)
        {          
            //设置软删除
            foreach (var entitytype in modelbuilder.model.getentitytypes())
            {               
                var parameter = expression.parameter(entitytype.clrtype);
                //查询类上面是否有owned(值对象)的特性
                var ownedmodeltype = parameter.type;
                var ownedattribute = attribute.getcustomattribute(ownedmodeltype, typeof(ownedattribute));
                if (ownedattribute == null)
                {
                    var propertymethodinfo = typeof(ef).getmethod("property").makegenericmethod(typeof(bool));
                    var isdeletedproperty =
                        expression.call(propertymethodinfo, parameter, expression.constant("isdeleted"));
                    binaryexpression compareexpression = expression.makebinary(expressiontype.equal, isdeletedproperty,
                        expression.constant(false));
                    var lambda = expression.lambda(compareexpression, parameter);
                    modelbuilder.entity(entitytype.clrtype).hasqueryfilter(lambda);
                }      
            }
        }
     

在这里需要过滤掉值对象的类,在值对象的类上面声明一个特性,通过该特性过滤掉该值对象, 如果该类是值对象就直接跳过,不过滤值对象ef core会给值对象附加一个isdeleted的字段,ef core执行中会报错,提示找不到该字段
owned是ef core 配置值对象的特性,可以去自定义特性,在每一个值对象上面声明,在onmodelcreating 过滤掉包含这个特性的类
最终实现的代码:

         public async task>> getuserlist(searchuserdto input)
         {
            expression> where = e => e.isdisable == false;
            if (!string.isnullorempty(input.searchname))
            {
                where = where.and(e => e.username.contains(input.searchname));
            }

            if (!string.isnullorempty(input.searchpwd))
            {
                where = where.and(e => e.userphone.contains(input.searchpwd));
            }
         
            var userlist = await _userrepository.loadentitylistasync(where, e => e.username, "asc", input.pageindex, input.pagesize);
            var total = await _userrepository.getentitiescountasync(where);
            var userdtolist = userlist.maptolist();

            headerresult> result = new headerresult>
            {
                issucceed = true,
                result = userdtolist,
                total = total
            };
            return result;
        }