zoukankan      html  css  js  c++  java
  • 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);
            }
  • 相关阅读:
    二分练习题4 查找最接近的元素 题解
    二分练习题5 二分法求函数的零点 题解
    二分练习题3 查找小于x的最大元素 题解
    二分练习题2 查找大于等于x的最小元素 题解
    二分练习题1 查找元素 题解
    code forces 1176 D. Recover it!
    code forces 1173 B. Nauuo and Chess
    code forces 1173 C. Nauuo and Cards
    吴恩达深度学习课程笔记-15
    吴恩达深度学习课程笔记-14
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/7858133.html
Copyright © 2011-2022 走看看