可以方便动态表达式实现业务处理
//用例1:连写 Expression<Func<Order, bool>> exp = Expressionable.Create<Order>() //创建表达式 .AndIF(p > 0, it => it.Id == p) .AndIF(name != null, it => it.Name == name && it.Sex==1) .ToExpression();//注意 这一句 不能少 var list = db.Queryable<Order>().Where(exp).ToList();//直接用就行了不需要判段 null和加true //用例2:分开写法 var expable= Expressionable.Create<Order>(); ...逻辑 expable.And(it.xx==x); ...逻辑 expable.And(it.yy==y); ...逻辑 var exp=expable.ToExpression();//要用变量 var exp= db.Queryable<Order>().Where(exp).ToList()//直接用就行了不需要判段 null和加true //用例3:多表查询 var exp=Expressionable.Create<Order,T2,T3>() .And((x,y,z)=>z.id==1).ToExpression();//注意 这一句 不能少 //技巧 WhereIF 有时候更方便 var list=db.Queryable<T>() .WhereIF(p>0,it=>it.p==p) .WhereIF(y>0,it=>it.y==y) .ToList()
我们可以用动态表达式实现 In ( name like 1, name like2 , name like3 ...) in 的模糊查询
var names= new string [] { "a","b"}; Expressionable<Order> exp = Expressionable.Create<Order>(); foreach (var item in names) { exp.Or(it => it.Name.Contains(item.ToString())); } var list= db.Queryable<Order>().Where(exp.ToExpression()).ToList();
生成的Sql
SELECT [Id], [Name], [Price], [CreateTime], [CustomId] FROM [Order] WHERE ( ([Name] like '%'+ CAST(@MethodConst0 AS NVARCHAR(MAX))+'%') OR ([Name] like '%'+ CAST(@MethodConst1 AS NVARCHAR(MAX))+'%') )
我们可以通过.Where().Where实现多个AND如果想实现 OR就只能借助动态表达式实现,query.or 让表达式中可以用OR
var exp = Expressionable.Create<Order>() .And(it => it.Id == 1) .Or(it=>it.Id==100 ) .ToExpression();//注意 这一句 不能少 var list= db.Queryable<Order>().Where(exp).ToList(); //Sql // where id=1 or id=100
var ex=Expressionable.Create<Student03>() .AndIf(id>0,it=>it.Id==id).ToExpression(); //如果一个条件没有有,你又不想生成1=1,可以结合whereif实现 var isEmpty = ((ex as LambdaExpression).Body as ConstantExpression)?.Value?.Equals(true)==true; var students = db.Queryable<Student03>() .WhereIF(!isEmpty, ex).ToList();
5.1.4.107-preview14+
//程序启动时配置 StaticConfig.DynamicExpressionParserType = typeof(DynamicExpressionParser); StaticConfig.DynamicExpressionParsingConfig = new ParsingConfig()//用到SqlFunc需要配置这个属性 { CustomTypeProvider = new SqlSugarTypeProvider()//这个类需要自已定义下面有 }; //导航属性动态 var list3 = db.Queryable<UnitPerson011>().Where("it", $"SqlFunc.Exists(it.Address.Id)").ToList(); //普通条件动态 var list4 = db.Queryable<UnitPerson011>().Where("it", $"it.Name={"a"}").ToList(); //动态类+动态条件 var list5=db.QueryableByObject(typeof(UnitPerson011)).Where("it", $"it.Address.Id=={1}").ToList(); //扩展类型 public class SqlSugarTypeProvider : DefaultDynamicLinqCustomTypeProvider { public override HashSet<Type> GetCustomTypes() { var customTypes = base.GetCustomTypes(); customTypes.Add(typeof(SqlFunc));//识别SqlFunc return customTypes; } } /****参数说明****/ //硬编码 Id>1 FormattableString str = $"it.Id>1"; //固定字段+参数化变量 Id>@p=1 FormattableString str2 = FormattableStringFactory.Create("it.Id>{0}",1); //动态字段+参数化变量 Id>@p=1 var p="it.Id"; FormattableString str2 = FormattableStringFactory.Create(p+">{0}",1);
该功能和表格查询可以互补
如果你们老大只让你用Ado,你们也可以把SqlSugar当成表达式解析器
var expContext = new SqlServerExpressionContext(); Expression<Func<IOrder, bool>> exp = it => it.id==1; expContext.Resolve(exp, ResolveExpressType.WhereSingle); var wheresql = expContext.Result.GetString(); var pars = expContext.Parameters; db.Queryable<Order>().Where(wheresql).AddParameters(pars).ToList();
ExpressionContext expContext=null; switch (dbtype) { case DbType.MySql: expContext = new MySqlExpressionContext(); break; case DbType.SqlServer: expContext = new SqlServerExpressionContext(); break; case DbType.Sqlite: expContext = new SqliteExpressionContext(); break; case DbType.Oracle: expContext = new OracleExpressionContext(); break; case DbType.PostgreSQL: expContext = new PostgreSQLExpressionContext(); break; case DbType.Dm: expContext = new DmExpressionContext(); break; case DbType.Kdbndp: expContext = new KdbndpExpressionContext(); break; default: throw new Exception("不支持");
基本和写EF一样常用的都会支持
Expression<Func<DataTestInfo2, bool>> exp = it => it.Bool2== b.Value; expContext.Resolve(exp, ResolveExpressType.WhereSingle); var value = expContext.Result.GetString(); var pars = expContext.Parameters; //( [Bool2] = @Bool20 ) //WhereSingle 没有别名 it
我们在写一个Like的例子
Expression<Func<Student, bool>> exp = it => it.Name.Contains(schoolData.Name); ExpressionContext expContext = new ExpressionContext(); expContext.Resolve(exp, ResolveExpressType.WhereMultiple); var value = expContext.Result.GetString(); var pars = expContext.Parameters; //([it].[Name] like '%'+@MethodConst0+'%') //WhereMultiple解析后会有别我 [it].
支持实体类解析、查询单个字段解析、匿名对象解析
Expression<Func<DataTestInfo2,DataTestInfo2>> exp=it=>new DataTestInfo2(){Bool1=it.Bool1,Bool2=it.Bool2}; ExpressionContext expContext = new ExpressionContext(); expContext.IsSingle = false; expContext.Resolve(exp, ResolveExpressType.SelectSingle); var selectorValue = expContext.Result.GetString(); var pars = expContext.Parameters; //[Bool1] AS [Bool1] , [Bool2] AS [Bool2]
例如orderby(it=>it.Name) 像这种我们就需要拿到Name
Expression<Func<Student, object>> exp = it => it.Name; ExpressionContext expContext = GetContext(); expContext.Resolve(exp, ResolveExpressType.FieldSingle); var selectorValue = expContext.Result.GetString(); //Name
统计单 个字段
Expression<Func<Student, object>> exp = it =>SqlFunc.AggregateAvg(it.Id); ExpressionContext expContext = GetContext(); expContext.Resolve(exp, ResolveExpressType.FieldMultiple); var selectorValue = expContext.Result.GetString(); //AVG([it].[Id])
var data=new MappingColumn() { DbColumnName = "OrderId", PropertyName = "Id", EntityName = "Order" }; expContext.MappingColumns.Add(data); Expression<Func<Order, bool>> exp = it => it.Id== 1; expContext.Resolve(exp, ResolveExpressType.WhereSingle); var value = expContext.Result.GetString(); var pars = expContext.Parameters; //( [OrderId] = 1)
方案1:
较高版本支持List.Any 和 List.All
.Where(it=>List.Any(s=>s.id==it.id&&s.name==it.id2))//高版本支持 OR .Where(it=>List.All(s=>s.id==it.id&&s.name==it.id2))//高版本支持 AND
方案2:
底层是用递归解析表达式,递归受到限制超过1000就会报错 ,我们可以通过设置线程最大堆栈解决
List<Order> list = null; var t=new System.Threading.Thread(async () => { var expable = SqlSugar.Expressionable.Create<Order>(); for (int i = 0; i < 1000; i++) { expable.Or(it => it.Id == i && it.Id == i); } var getOrderBy = db.Queryable<Order>().Where(expable.ToExpression()).ToListAsync(); var x = 0; },int.MaxValue);//设置线程栈 t.Start(); Thread.Sleep(1000);//设置等待时间保证这个 线程执行完
2016 © donet5.comApache Licence 2.0