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);
            }
  • 相关阅读:
    视频实例分割 | Target-Aware Adaptive Tracking for Unsupervised Video Object Segmentation
    目标检测算法:Selective Search(选择性搜索)简述
    [2020BUAA软工助教]期末总结
    WPF,数据验证方案,验证通过才能继续下一步
    WPF:解决数据验证ValidationRule与按钮Canexcute联动的问题
    解决mininet运行报错“ImportError: No module named mininet.log”
    交易所对接ERC20钱包端口要多长时间?
    尺子的刻度
    学习java的第四周
    学习java的第三周
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/7858133.html
Copyright © 2011-2022 走看看