动态表达式

1、动态表达式

 1.1 用例

可以方便动态表达式实现业务处理

//用例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.AndIF(xx>0,it.xx==x);
...逻辑
expable.AndIF(yy>0,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();//注意 这一句 不能少

 1.2 拓展用例

我们可以用动态表达式实现 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))+'%')
                     )

 1.3 Queyable.Or

我们可以通过.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

2、解析表达式

如果你们老大只让你用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();

 2.1 声名表达式解析器

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("不支持");

 2.2 Where条件的解析

基本和写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].

 2.3 Select的解析

支持实体类解析、查询单个字段解析、匿名对象解析

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]

 2.4 字段名称的解析

例如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])

 2.5 更改列名

expContext.MappingColumns.Add(new MappingColumn() { DbColumnName = "OrderId", PropertyName = "Id", EntityName = "Order" });
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)


文档:SqlSugar5.0