DDD领域模型查询方法实现(八)

在DDD.Domain工程文件夹Repository下创建RequestPage类:

  public class RequestPage
    {
        public RequestPage(int pagesize, int currentpage, string orderproperty, string order)
        {
            this.PageSize = pagesize;
            this.CurrentPage = currentpage;
            this.Orderproperty = orderproperty;
            this.Order = order;
        }

        public int PageSize { get; }
        public int CurrentPage { get; }
        public string Orderproperty { get; }
        public string Order { get; }
    }

 在 Repository文件夹IRepository接口中定义:

  //返回聚合根分页的方法
        List<TAggreateRoot> GetByConditionPages(Expression<Func<TAggreateRoot, bool>> condition,
            RequestPage request, out int totalcount);
        List<TAggreateRoot> GetByConditionPages(List<Conditions> condition,
            RequestPage request, out int totalcount);
    
        List<TDTO> GetByConditionPages<TDTO>(Expression<Func<TAggreateRoot, bool>> condition,
    RequestPage request, out int totalcount);
        List<TDTO> GetByConditionPages<TDTO>(List<Conditions> condition,
RequestPage request, out int totalcount);

 在DDD.Repository工程ResultPage类中:(结果集)

 public class ResultPage<T> : IQueryable<T>
    {
        public ResultPage(int totalpages, int totalcounts, int currentpage, List<T> data)
        {
            this.TotalPages = totalpages;
            this.TotalCounts = totalcounts;
            this.CurrentPage = currentpage;
            this.Data = data;
        }

        public int TotalPages { get; }
        public int TotalCounts { get; }
        public int Pagesize { get; }
        public int CurrentPage { get; }
        public List<T> Data { get; }

        public Type ElementType
        {
            get
            {
                return typeof(T);

            }
        }

        public Expression Expression
        {
            get;
        }

        public IQueryProvider Provider
        {
            get;
        }

        public IEnumerator<T> GetEnumerator()
        {
            return Data.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return Data.GetEnumerator();
        }
    }

在EFRepository中实现分页的方法:

public List<TAggreateRoot> GetByConditionPages(List<Conditions> condition, RequestPage request, out int totalcount)
        {
            return GetByConditionPages(WhereLamdaConverter.Where<TAggreateRoot>(condition), request, out totalcount);
        }

        public List<TAggreateRoot> GetByConditionPages(Expression<Func<TAggreateRoot, bool>> condition, RequestPage request, out int totalcount)
        {
            var query = orderdbcontext.Set<TAggreateRoot>().Where(condition);
            var skip = (request.CurrentPage - 1) * request.PageSize;
            var take = request.PageSize;
            var queryresult =
                request.Order == "ASC" ? query.OrderBy(p => new { Order = request.Orderproperty })
                .Skip(skip).Take(take) :
                query.OrderByDescending(p => new { Order = request.Orderproperty })
                .Skip(skip).Take(take);
            totalcount = query.Count();
          
            return new ResultPage<TAggreateRoot>(totalcount / request.PageSize, totalcount,
                request.CurrentPage, queryresult.ToList()).ToList();
        }

        public List<TDTO> GetByConditionPages<TDTO>(List<Conditions> condition, RequestPage request, out int totalcount)
        {
            return GetByConditionPages<TDTO>(WhereLamdaConverter.Where<TAggreateRoot>(condition), request, out totalcount);
        }

        public List<TDTO> GetByConditionPages<TDTO>(Expression<Func<TAggreateRoot, bool>> condition, RequestPage request, out int totalcount)
        {
            var query = orderdbcontext.Set<TAggreateRoot>().Where(condition);
            var skip = (request.CurrentPage - 1) * request.PageSize;
            var take = request.PageSize;
            var queryresult =
                request.Order == "ASC" ? query.OrderBy(p => new { Order = request.Orderproperty })
                .Skip(skip).Take(take) :
                query.OrderByDescending(p => new { Order = request.Orderproperty })
                .Skip(skip).Take(take);
            totalcount = query.Count();
            var queryresults = queryresult.ToList();
            var queryresultdtos = new List<TDTO>();
            if (totalcount > 0)
            {
                foreach (var q in queryresults)
                {
                    var queryresultdto = Mapper.Map<TAggreateRoot, TDTO>(q);
                    queryresultdtos.Add(queryresultdto);
                }
            }
            return new ResultPage<TDTO>(totalcount / request.PageSize, totalcount, request.CurrentPage,
                queryresultdtos).ToList();
        }

 在DDD.Infrastructure中新建LamdaFilterConvert(做筛选的转化器):--Conditions

public class Conditions
    {
        //具体插叙的字段
        public string Field { get; set; }
        //操作符
        public string Operator { get; set; }
        //字段的值
        public string Value { get; set; }
        //字段查询组合的关系
        public string Relation { get; set; }
        //把界面传的值转成List集合
        public static List<Conditions> BuildConditions(string[] fields, string[] operators, string[] values,
            string[] relations)
        {
            var conditions = fields.Select((t, i) => new Conditions
            {
                Field = t,
                Operator = operators[i],
                Value = values[i],
                Relation = relations[i]
            }).ToList();
            return conditions;
        }
    }

 带有where的Lambda表达式转换器:

 public static class WhereLamdaConverter
    {
        private class ParameterReplacer : ExpressionVisitor
        {
            public ParameterExpression ParameterExpression { get; private set; }

            public ParameterReplacer(ParameterExpression paramExp)
            {
                this.ParameterExpression = paramExp;
            }

            public Expression Replace(Expression exp)
            {
                return this.Visit(exp);
            }

            protected override Expression VisitParameter(ParameterExpression p)
            {
                return this.ParameterExpression;
            }
        }

        public static Expression<Func<T, bool>> True<T>()
        {
            return item => true;
        }

        public static Expression<Func<T, bool>> False<T>()
        {
            return item => false;
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight)
        {
            var candidateExpr = Expression.Parameter(typeof(T), "item");
            var parameterReplacer = new ParameterReplacer(candidateExpr);

            var left = parameterReplacer.Replace(expLeft.Body);
            var right = parameterReplacer.Replace(expRight.Body);
            var body = Expression.And(left, right);

            return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
        }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight)
        {
            var candidateExpr = Expression.Parameter(typeof(T), "item");
            var parameterReplacer = new ParameterReplacer(candidateExpr);
            var left = parameterReplacer.Replace(expLeft.Body);
            var right = parameterReplacer.Replace(expRight.Body);
            var body = Expression.Or(left, right);
            return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
        }
        public static Expression<Func<T, bool>> Parse<T>(string member, string logic, string matchValue)
        {
            if (string.IsNullOrEmpty(member))
            {
                throw new ArgumentNullException("member");
            }
            PropertyInfo keyProperty;
            ParameterExpression pExp;
            keyProperty = typeof(T).GetProperties().FirstOrDefault(item => item.Name.ToLower().Equals(member.Trim().ToLower()));
            pExp = Expression.Parameter(typeof(T), "p");

            if (keyProperty == null)
            {
                throw new ArgumentException("member不存在");
            }

            Expression memberExp = Expression.MakeMemberAccess(pExp, keyProperty);
            if (logic != "Contains")
            {
                bool memberIsNullableType = keyProperty.PropertyType.IsGenericType && keyProperty.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);

                if (memberIsNullableType)
                {
                    memberExp = Expression.MakeMemberAccess(memberExp, keyProperty.PropertyType.GetProperty("Value"));
                }

                Type valueType = keyProperty.PropertyType;
                if (memberIsNullableType == true)
                {
                    valueType = valueType.GetGenericArguments().FirstOrDefault();
                }

                object value = matchValue;
                if (valueType == typeof(string) == false)
                {
                    if (valueType != null)
                        value = valueType.GetMethod("Parse", new[] { typeof(string) }).Invoke(null, new[] { value });
                }

                var valueExp = Expression.Constant(value, valueType);

                var expMethod = typeof(Expression).GetMethod(logic, new Type[] { typeof(Expression), typeof(Expression) });


                var body = expMethod.Invoke(null, new object[] { memberExp, valueExp }) as Expression;
                var lamdaexpression = Expression.Lambda(body, pExp) as Expression<Func<T, bool>>;
                return lamdaexpression;
            }
            else
            {
                MethodCallExpression body = null;
                body = Expression.Call(memberExp, typeof(string).GetMethod(logic), Expression.Constant(matchValue, typeof(string)));
                var lamdaexpression = Expression.Lambda(body, pExp) as Expression<Func<T, bool>>;
                return lamdaexpression;
            }
        }


        public static Expression<Func<T, bool>> Where<T>(List<Conditions> conditions)
        {
            Expression<Func<T, bool>> expression = null;
            if (conditions != null && conditions.Count > 0)
            {
                var firstexpression =
                    Parse<T>(conditions[0].Field, conditions[0].Operator, conditions[0].Value);
                if (conditions.Count <= 1)
                    return firstexpression;
                for (var i = 1; i < conditions.Count; i++)
                {
                    var rightexpression =
                        Parse<T>(conditions[i].Field, conditions[i].Operator, conditions[i].Value);
                    expression = conditions[i - 1].Relation.ToUpper().Equals("AND")
                        ? firstexpression.And(rightexpression)
                        : firstexpression.Or(rightexpression);
                }
            }
            return expression;
        }

      
    }

 把映射的代码移到DDD.Application工程ProductAppService类中:

  IRepository<Product> productrepository = ServiecLocator.Instance.GetService(typeof(IRepository<Product>))
           as IRepository<Product>;

        Product product;
        //public void CreateProduct(string productname, string color, string size,
        //    int count, decimal unitprice, string categoryname, string description)
        //{           
        //    product.CreateProduct(productname, color, size, count, unitprice, categoryname, description);
        //    context.Commit();
        //}

        public ProductAppService()
        {
            product = new Product(productrepository);
            //完成映射的创建
            ProductMapping();
        }
        //在调用构造函数的时候完成映射的创建
        private void ProductMapping()
        {
            //从界面的DTO持久化领域对象
            var mapin = Mapper.CreateMap<ProductDTO, Product>();
            //指定属性的对应关系
            mapin.ConstructProjectionUsing(p => new Product
            {
                ProductName = p.Name,
                Size = p.Size,
                Color = p.Color,
                Count = p.Amount,
                UnitPrice = p.UnitPrice,
                ProductCategory = new ProductCategory
                {
                    Id = Guid.NewGuid(),
                    CategoryName = p.PCategoryName,
                    Description = p.PDescription
                }
            });
            //返回界面的东西
            var mapout = Mapper.CreateMap<Product, ProductDTO>();
            mapout.ConstructProjectionUsing(p => new ProductDTO
            {
                Name = p.ProductName,
                Size = p.Size,
                Color = p.Color,
                UnitPrice = p.UnitPrice,
                PCategoryName = p.ProductCategory.CategoryName,
                PDescription = p.ProductCategory.Description,
                Amount = p.Count
            });
        }

  /// <summary>
        /// 被前端调用的方法
        /// </summary>
        /// <param name="conditions"></param>
        /// <param name="request"></param>
        /// <param name="totalcount"></param>
        /// <returns></returns>
        public List<ProductDTO> GetProductDTOSByCondition(List<Conditions> conditions,
            RequestPage request, out int totalcount)
        {
            return productrepository.GetByConditionPages<ProductDTO>(conditions, request,
               out totalcount);
        }

 

转载于:https://www.cnblogs.com/sunliyuan/p/7858133.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值