在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);
}