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

时间:2021-07-12 19:42:53

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