.NetCore使用Linq动态拼接Expression表达式条件来实现对EF、EFCor。。。

更新时间:2023-07-04 14:00:50 阅读: 评论:0

.NetCore使⽤Linq动态拼接Expression表达式条件来实现对EF、EFCor。。。
相信在使⽤EF的时候对查询条件或者排序上的处理令⼈⼼烦,下⾯我们就来动态拼接表达式解决这⼀问题
当我们在查询中使⽤Where的时候可以看到如下参数
下⾯我们就来扩展 Expression<Func<T,bool>> 这个参数
第⼀步:建⽴处理功能类
⾸先我们要创建⼀个查询条件转化为表达式的泛型功能类如 UosoExpressionParr<T> ⾄于为什么要⽤泛型类⽬的很明确就是为了适配不同的模型参数转化条件为表达式那么处理⼀个⽅法来接受条件返回表达式,条件可以按照⾃⼰的模式去设置
public Expression<Func<T, bool>> ParrConditions(IEnumerable<UosoConditions> conditions)
{
/
/将条件转化成表达是的Body
var query = ParExpressionBody(conditions);
return Expression.Lambda<Func<T, bool>>(query, parameter);
}
public class UosoConditions
{
///<summary>
///字段名称
///</summary>
public string Key { get; t; }
///<summary>
/
//值
///</summary>
public string Value { get; t; }
///<summary>
///值类型
///</summary>
在烈日和暴雨下public string ValueType { get; t; }
///<summary>
///
///</summary>
public UosoOperatorEnum Operator { get; t; }
}
第⼆步:条件转表达式具体处理
具体去实现  ParExpressionBody 条件枚举提供操作⽅式如:(like 、 = 、!= 、>  、<  、>=  、<=  、in 、 between)
橡皮泥兔子private Expression ParExpressionBody(IEnumerable<UosoConditions> conditions)
{
if (conditions == null || conditions.Count() == 0)
{
描写元宵节的诗
return Expression.Constant(true, typeof(bool));
}
el if (conditions.Count() == 1)
{
return ParCondition(conditions.First());
}
el
{
Expression left = ParCondition(conditions.First());
Expression right = ParExpressionBody(conditions.Skip(1));
return Expression.AndAlso(left, right);
}
}
private Expression ParCondition(UosoConditions condition)
{
ParameterExpression p = parameter;
Expression key = Expression.Property(p, condition.Key);
Expression value = Expression.Constant(condition.Value);
新春佳节祝福语
switch (condition.Operator)
{
计算机怎么关机ca UosoOperatorEnum.Contains:
return Expression.Call(key, typeof(string).GetMethod("Contains",new Type[] { typeof(string) }), value);
ca UosoOperatorEnum.Equal:
return Expression.Equal(key, Expression.Convert(value, key.Type));
ca UosoOperatorEnum.Greater:
return Expression.GreaterThan(key, Expression.Convert(value, key.Type));
ca UosoOperatorEnum.GreaterEqual:
return Expression.GreaterThanOrEqual(key, Expression.Convert(value, key.Type));
ca UosoOperatorEnum.Less:
return Expression.LessThan(key, Expression.Convert(value, key.Type));
ca UosoOperatorEnum.LessEqual:
return Expression.LessThanOrEqual(key, Expression.Convert(value, key.Type));
ca UosoOperatorEnum.NotEqual:
return Expression.NotEqual(key, Expression.Convert(value, key.Type));
ca UosoOperatorEnum.In:
return ParaIn(p, condition);
ca UosoOperatorEnum.Between:
return ParaBetween(p, condition);
default:
throw new NotImplementedException("不⽀持此操作");
}
}
这⾥对 In  和between 做了特殊处理
private Expression ParaBetween(ParameterExpression parameter, UosoConditions conditions)
{
ParameterExpression p = parameter;
Expression key = Expression.Property(p, conditions.Key);
var valueArr = conditions.Value.Split(',');
电气预算
if (valueArr.Length != 2)
{
throw new NotImplementedException("ParaBetween参数错误");
}
try
噱头的读音
{
int.Par(valueArr[0]);
int.Par(valueArr[1]);
}
catch {
throw new NotImplementedException("ParaBetween参数只能为数字");
}
Expression expression = Expression.Constant(true, typeof(bool));
我尊敬的人作文//开始位置
Expression startvalue = Expression.Constant(int.Par(valueArr[0]));
Expression start = Expression.GreaterThanOrEqual(key, Expression.Convert(startvalue, key.Type));
Expression endvalue = Expression.Constant(int.Par(valueArr[1]));
Expression end = Expression.GreaterThanOrEqual(key, Expression.Convert(endvalue, key.Type));
return Expression.AndAlso(start, end);
}
private Expression ParaIn(ParameterExpression parameter, UosoConditions conditions)
{
ParameterExpression p = parameter;
Expression key = Expression.Property(p, conditions.Key);
var valueArr = conditions.Value.Split(',');
Expression expression = Expression.Constant(true, typeof(bool));
foreach (var itemVal in valueArr)
{
Expression value = Expression.Constant(itemVal);
Expression right = Expression.Equal(key, Expression.Convert(value, key.Type));
expression = Expression.Or(expression, right);
}
return expression;
}
第三步:扩展分页、排序、查询条件
扩展 IQueryable<T> 就OK了,下⾯是我扩展的查询排序分页处理
扩展查询
public static IQueryable<T> QueryConditions<T>(this IQueryable<T> query, IEnumerable<UosoConditions> conditions)
{
var parr = new UosoExpressionParr<T>();
var filter = parr.ParrConditions(conditions);
return query.Where(filter);
}
扩展多条件排序
public static IQueryable<T> OrderConditions<T>(this IQueryable<T> query, IEnumerable<UosoOrderConditions> orderConditions)        {
foreach (var orderinfo in orderConditions)
{
var t = typeof(T);
var propertyInfo = t.GetProperty(orderinfo.Key);
var parameter = Expression.Parameter(t);
Expression propertySelector = Expression.Property(parameter, propertyInfo);
var orderby = Expression.Lambda<Func<T, object>>(propertySelector, parameter);
if (orderinfo.Order == OrderSequence.DESC)
query = query.OrderByDescending(orderby);
el
query = query.OrderBy(orderby);
}
return query;
}
扩展分页
public static IQueryable<T> Pager<T>(this IQueryable<T> query, int pageindex, int pagesize,out int itemCount)
{
itemCount = query.Count();
return query.Skip((pageindex - 1) * pagesize).Take(pagesize);
}
扩展基本完成了,接下来就是使⽤⽅式下⾯是我写的查询分页⽅式
第四步:具体使⽤⽅式
public IList<IdentityUr> GetPagedList2(IEnumerable<UosoConditions>  conditions,IEnumerable<UosoOrderConditions> orderConditions,int pageIndex, int pageSize,out int itemcount)        {
return _urManager.Urs.AsNoTracking().QueryConditions(conditions).OrderConditions(orderConditions).Pager(pageIndex, pageSize, out itemcount).ToList();
}
你需要构建相关的查询排序集合类就⾏了如下:
List<UosoConditions> uosoConditions = new List<UosoConditions>() {
new UosoConditions { Key = "UrName", Operator = UosoOperatorEnum.Contains, Value = "1,3", ValueType = "string" }
};
List<UosoOrderConditions> orderConditions = new List<UosoOrderConditions> {
new UosoOrderConditions{
Key="UrName",
Order = OrderSequence.DESC
},
new UosoOrderConditions{
Key="PhoneNumber",
Order = OrderSequence.DESC
}
};
int itemcount = 0;
var list = _urServices.GetPagedList2(uosoConditions, orderConditions, pageindex, pagesize, out itemcount);
第五步:结合前端分页样式实现整体(之前的有介绍)
ViewBag.Option = new UosoPagerOption()
{
ItemCount = itemcount,
PageSize = pagesize,
PageIndex = pageindex,
CountNum = 5,
Url = Request.Path.Value,
Query = Request.Query
};
以上是实现分页的全部过程,这⾥值得注意的是在 like查询 Contains的时候,在.NetCore中需要如下这样写,不然可能会出现反射多次被实例化的问题
typeof(string).GetMethod("Contains",new Type[] { typeof(string) })
如果是.Net Framework 中为如下⽅式
typeof(string).GetMethod("Contains")

本文发布于:2023-07-04 14:00:50,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1078001.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:条件   表达式   查询   排序   参数   实现   作文
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图