From 2707f801af10fba6819cf4df875b5b8437365278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E9=95=87=E6=B1=90?= <8907060@qq.com> Date: Mon, 30 Jul 2018 19:57:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0Sql=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Builders/Conditions/EqualCondition.cs | 2 +- .../Builders/Conditions/GreaterCondition.cs | 32 ++ .../Conditions/GreaterEqualCondition.cs | 32 ++ .../Builders/Conditions/LessCondition.cs | 32 ++ .../Builders/Conditions/LessEqualCondition.cs | 32 ++ .../Builders/Conditions/LikeCondition.cs | 32 ++ .../Builders/Conditions/NotEqualCondition.cs | 32 ++ .../Conditions/SqlConditionFactory.cs | 32 +- .../Datas/Sql/Queries/Builders/ISqlBuilder.cs | 49 ++- .../Sql/Queries/Builders/SqlBuilderBase.cs | 96 +++++- src/Util/Datas/Sql/Queries/ISqlQuery.cs | 49 ++- src/Util/Datas/Sql/Queries/SqlQueryBase.cs | 77 ++++- src/Util/Helpers/Lambda.cs | 88 ++++- .../Dapper/SqlServer/SqlServerBuilderTest.cs | 240 ++++++++++++- .../Sql/Conditions/GreaterConditionTest.cs | 18 + .../Conditions/GreaterEqualConditionTest.cs | 18 + .../Datas/Sql/Conditions/LessConditionTest.cs | 18 + .../Sql/Conditions/LessEqualConditionTest.cs | 18 + .../Datas/Sql/Conditions/LikeConditionTest.cs | 18 + .../Sql/Conditions/NotEqualConditionTest.cs | 18 + test/Util.Tests/Helpers/LambdaTest.cs | 315 ++++++++++++++++++ 21 files changed, 1214 insertions(+), 34 deletions(-) create mode 100644 src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterCondition.cs create mode 100644 src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterEqualCondition.cs create mode 100644 src/Util/Datas/Sql/Queries/Builders/Conditions/LessCondition.cs create mode 100644 src/Util/Datas/Sql/Queries/Builders/Conditions/LessEqualCondition.cs create mode 100644 src/Util/Datas/Sql/Queries/Builders/Conditions/LikeCondition.cs create mode 100644 src/Util/Datas/Sql/Queries/Builders/Conditions/NotEqualCondition.cs create mode 100644 test/Util.Tests/Datas/Sql/Conditions/GreaterConditionTest.cs create mode 100644 test/Util.Tests/Datas/Sql/Conditions/GreaterEqualConditionTest.cs create mode 100644 test/Util.Tests/Datas/Sql/Conditions/LessConditionTest.cs create mode 100644 test/Util.Tests/Datas/Sql/Conditions/LessEqualConditionTest.cs create mode 100644 test/Util.Tests/Datas/Sql/Conditions/LikeConditionTest.cs create mode 100644 test/Util.Tests/Datas/Sql/Conditions/NotEqualConditionTest.cs diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/EqualCondition.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/EqualCondition.cs index 85aef9ad..6a885de5 100644 --- a/src/Util/Datas/Sql/Queries/Builders/Conditions/EqualCondition.cs +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/EqualCondition.cs @@ -13,7 +13,7 @@ private readonly string _parameter; /// - /// 初始化And连接条件 + /// 初始化Sql相等查询条件 /// /// 列名 /// 参数 diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterCondition.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterCondition.cs new file mode 100644 index 00000000..86795937 --- /dev/null +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterCondition.cs @@ -0,0 +1,32 @@ +namespace Util.Datas.Sql.Queries.Builders.Conditions { + /// + /// Sql大于查询条件 + /// + public class GreaterCondition : ICondition { + /// + /// 列名 + /// + private readonly string _column; + /// + /// 参数 + /// + private readonly string _parameter; + + /// + /// 初始化Sql大于查询条件 + /// + /// 列名 + /// 参数 + public GreaterCondition( string column, string parameter ) { + _column = column; + _parameter = parameter; + } + + /// + /// 获取查询条件 + /// + public string GetCondition() { + return $"{_column}>{_parameter}"; + } + } +} \ No newline at end of file diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterEqualCondition.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterEqualCondition.cs new file mode 100644 index 00000000..e51fb007 --- /dev/null +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/GreaterEqualCondition.cs @@ -0,0 +1,32 @@ +namespace Util.Datas.Sql.Queries.Builders.Conditions { + /// + /// Sql大于等于查询条件 + /// + public class GreaterEqualCondition : ICondition { + /// + /// 列名 + /// + private readonly string _column; + /// + /// 参数 + /// + private readonly string _parameter; + + /// + /// 初始化Sql大于等于查询条件 + /// + /// 列名 + /// 参数 + public GreaterEqualCondition( string column, string parameter ) { + _column = column; + _parameter = parameter; + } + + /// + /// 获取查询条件 + /// + public string GetCondition() { + return $"{_column}>={_parameter}"; + } + } +} \ No newline at end of file diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/LessCondition.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/LessCondition.cs new file mode 100644 index 00000000..32babd6e --- /dev/null +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/LessCondition.cs @@ -0,0 +1,32 @@ +namespace Util.Datas.Sql.Queries.Builders.Conditions { + /// + /// Sql小于查询条件 + /// + public class LessCondition : ICondition { + /// + /// 列名 + /// + private readonly string _column; + /// + /// 参数 + /// + private readonly string _parameter; + + /// + /// 初始化Sql小于查询条件 + /// + /// 列名 + /// 参数 + public LessCondition( string column, string parameter ) { + _column = column; + _parameter = parameter; + } + + /// + /// 获取查询条件 + /// + public string GetCondition() { + return $"{_column}<{_parameter}"; + } + } +} \ No newline at end of file diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/LessEqualCondition.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/LessEqualCondition.cs new file mode 100644 index 00000000..41e86318 --- /dev/null +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/LessEqualCondition.cs @@ -0,0 +1,32 @@ +namespace Util.Datas.Sql.Queries.Builders.Conditions { + /// + /// Sql小于等于查询条件 + /// + public class LessEqualCondition : ICondition { + /// + /// 列名 + /// + private readonly string _column; + /// + /// 参数 + /// + private readonly string _parameter; + + /// + /// 初始化Sql小于等于查询条件 + /// + /// 列名 + /// 参数 + public LessEqualCondition( string column, string parameter ) { + _column = column; + _parameter = parameter; + } + + /// + /// 获取查询条件 + /// + public string GetCondition() { + return $"{_column}<={_parameter}"; + } + } +} \ No newline at end of file diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/LikeCondition.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/LikeCondition.cs new file mode 100644 index 00000000..6edf0f36 --- /dev/null +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/LikeCondition.cs @@ -0,0 +1,32 @@ +namespace Util.Datas.Sql.Queries.Builders.Conditions { + /// + /// Sql模糊查询条件 + /// + public class LikeCondition : ICondition { + /// + /// 列名 + /// + private readonly string _column; + /// + /// 参数 + /// + private readonly string _parameter; + + /// + /// 初始化Sql模糊查询条件 + /// + /// 列名 + /// 参数 + public LikeCondition( string column, string parameter ) { + _column = column; + _parameter = parameter; + } + + /// + /// 获取查询条件 + /// + public string GetCondition() { + return $"{_column} Like {_parameter}"; + } + } +} \ No newline at end of file diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/NotEqualCondition.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/NotEqualCondition.cs new file mode 100644 index 00000000..24683dd5 --- /dev/null +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/NotEqualCondition.cs @@ -0,0 +1,32 @@ +namespace Util.Datas.Sql.Queries.Builders.Conditions { + /// + /// Sql不相等查询条件 + /// + public class NotEqualCondition : ICondition { + /// + /// 列名 + /// + private readonly string _column; + /// + /// 参数 + /// + private readonly string _parameter; + + /// + /// 初始化Sql不相等查询条件 + /// + /// 列名 + /// 参数 + public NotEqualCondition( string column, string parameter ) { + _column = column; + _parameter = parameter; + } + + /// + /// 获取查询条件 + /// + public string GetCondition() { + return $"{_column}!={_parameter}"; + } + } +} \ No newline at end of file diff --git a/src/Util/Datas/Sql/Queries/Builders/Conditions/SqlConditionFactory.cs b/src/Util/Datas/Sql/Queries/Builders/Conditions/SqlConditionFactory.cs index 008ffa0a..7ed270af 100644 --- a/src/Util/Datas/Sql/Queries/Builders/Conditions/SqlConditionFactory.cs +++ b/src/Util/Datas/Sql/Queries/Builders/Conditions/SqlConditionFactory.cs @@ -16,22 +16,22 @@ namespace Util.Datas.Sql.Queries.Builders.Conditions { switch( @operator ) { case Operator.Equal: return new EqualCondition( name, parameter ); - //case Operator.NotEqual: - // return new NotEqualCondition( name, prefix ); - //case Operator.Greater: - // return new GreaterCondition( name, prefix ); - //case Operator.Less: - // return new LessCondition( name, prefix ); - //case Operator.GreaterEqual: - // return new GreaterEqualCondition( name, prefix ); - //case Operator.LessEqual: - // return new LessEqualCondition( name, prefix ); - //case Operator.Contains: - // return new LikeCondition( name, prefix ); - //case Operator.Starts: - // return new LikeCondition( name, prefix ); - //case Operator.Ends: - // return new LikeCondition( name, prefix ); + case Operator.NotEqual: + return new NotEqualCondition( name, parameter ); + case Operator.Greater: + return new GreaterCondition( name, parameter ); + case Operator.Less: + return new LessCondition( name, parameter ); + case Operator.GreaterEqual: + return new GreaterEqualCondition( name, parameter ); + case Operator.LessEqual: + return new LessEqualCondition( name, parameter ); + case Operator.Contains: + return new LikeCondition( name, parameter ); + case Operator.Starts: + return new LikeCondition( name, parameter ); + case Operator.Ends: + return new LikeCondition( name, parameter ); } throw new NotImplementedException( $"运算符 {@operator.Description()} 未实现" ); } diff --git a/src/Util/Datas/Sql/Queries/Builders/ISqlBuilder.cs b/src/Util/Datas/Sql/Queries/Builders/ISqlBuilder.cs index 4f1eac5a..91252c6b 100644 --- a/src/Util/Datas/Sql/Queries/Builders/ISqlBuilder.cs +++ b/src/Util/Datas/Sql/Queries/Builders/ISqlBuilder.cs @@ -32,7 +32,7 @@ namespace Util.Datas.Sql.Queries.Builders { /// /// 列名 /// 表别名 - ISqlBuilder Select( Expression> columns,string tableAlias = null ); + ISqlBuilder Select( Expression> columns, string tableAlias = null ) where TEntity : class; /// /// 设置表名 /// @@ -41,17 +41,62 @@ namespace Util.Datas.Sql.Queries.Builders { /// 架构名 ISqlBuilder From( string table, string alias = null, string schema = null ); /// + /// 设置表名 + /// + /// 别名 + /// 架构名 + ISqlBuilder From( string alias = null, string schema = null ) where TEntity : class; + /// /// And连接条件 /// /// 查询条件 ISqlBuilder And( ICondition condition ); /// - /// 设置条件 + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 表别名 + ISqlBuilder Where( Expression> expression, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 运算符 + /// 表别名 + ISqlBuilder Where( Expression> expression, object value, Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 /// /// 列名 /// 值 /// 运算符 /// 表别名 ISqlBuilder Where( string column, object value, Operator @operator = Operator.Equal, string tableAlias = null ); + /// + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 该值为true时添加查询条件,否则忽略 + /// 表别名 + ISqlBuilder WhereIf( Expression> expression, bool condition, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + ISqlBuilder WhereIf( Expression> expression, object value, bool condition, Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 + /// + /// 列名 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + ISqlBuilder WhereIf( string column, object value, bool condition, Operator @operator = Operator.Equal, string tableAlias = null ); } } diff --git a/src/Util/Datas/Sql/Queries/Builders/SqlBuilderBase.cs b/src/Util/Datas/Sql/Queries/Builders/SqlBuilderBase.cs index 6801e0e2..b8703316 100644 --- a/src/Util/Datas/Sql/Queries/Builders/SqlBuilderBase.cs +++ b/src/Util/Datas/Sql/Queries/Builders/SqlBuilderBase.cs @@ -16,6 +16,10 @@ namespace Util.Datas.Sql.Queries.Builders { #region 字段 + /// + /// 表别名集合 + /// + private readonly IDictionary _tableAlias; /// /// 参数集合 /// @@ -33,6 +37,7 @@ namespace Util.Datas.Sql.Queries.Builders { /// 初始化Sql生成器 /// protected SqlBuilderBase() { + _tableAlias = new Dictionary(); _params = new Dictionary(); Columns = new List(); } @@ -147,7 +152,7 @@ namespace Util.Datas.Sql.Queries.Builders { /// /// 列名 /// 表别名 - public virtual ISqlBuilder Select( Expression> columns, string tableAlias = null ) { + public virtual ISqlBuilder Select( Expression> columns, string tableAlias = null ) where TEntity : class { if( columns == null ) return this; return Select( Lambda.GetNames( columns ).Join(), tableAlias ); @@ -170,6 +175,17 @@ namespace Util.Datas.Sql.Queries.Builders { return this; } + /// + /// 设置表名 + /// + /// 别名 + /// 架构名 + public ISqlBuilder From( string alias = null, string schema = null ) where TEntity : class { + if( string.IsNullOrWhiteSpace( alias ) == false ) + _tableAlias.Add( typeof( TEntity ), alias ); + return From( typeof( TEntity ).Name, alias, schema ); + } + #endregion #region And(And连接条件) @@ -185,10 +201,43 @@ namespace Util.Datas.Sql.Queries.Builders { #endregion - #region Where(设置条件) + #region Where(设置查询条件) /// - /// 设置条件 + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 表别名 + public ISqlBuilder Where( Expression> expression, string tableAlias = null ) where TEntity : class { + return Where( Lambda.GetLastName( expression ), Lambda.GetValue( expression ), Lambda.GetOperator( expression ).SafeValue(), GetTableAlias( tableAlias ) ); + } + + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 运算符 + /// 表别名 + public ISqlBuilder Where( Expression> expression, object value, + Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class { + return Where( Lambda.GetLastName( expression ), value, @operator, GetTableAlias( tableAlias ) ); + } + + /// + /// 获取表别名 + /// + protected string GetTableAlias( string tableAlias ) { + if( string.IsNullOrWhiteSpace( tableAlias ) == false ) + return tableAlias; + var type = typeof( TEntity ); + if( _tableAlias.ContainsKey( type ) ) + return _tableAlias[type]; + return string.Empty; + } + + /// + /// 设置查询条件 /// /// 列名 /// 值 @@ -241,6 +290,47 @@ namespace Util.Datas.Sql.Queries.Builders { #endregion + /// + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 该值为true时添加查询条件,否则忽略 + /// 表别名 + public ISqlBuilder WhereIf( Expression> expression, bool condition, string tableAlias = null ) where TEntity : class { + if( condition ) + return Where( expression, tableAlias ); + return this; + } + + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + public ISqlBuilder WhereIf( Expression> expression, object value, bool condition, + Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class { + if( condition ) + return Where( expression, value, @operator, tableAlias ); + return this; + } + + /// + /// 设置查询条件 + /// + /// 列名 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + public ISqlBuilder WhereIf( string column, object value, bool condition, Operator @operator = Operator.Equal, string tableAlias = null ) { + if( condition ) + return Where( column, value, @operator, tableAlias ); + return this; + } + #region 获取子句 /// diff --git a/src/Util/Datas/Sql/Queries/ISqlQuery.cs b/src/Util/Datas/Sql/Queries/ISqlQuery.cs index a5496bdd..e1061bb9 100644 --- a/src/Util/Datas/Sql/Queries/ISqlQuery.cs +++ b/src/Util/Datas/Sql/Queries/ISqlQuery.cs @@ -38,7 +38,7 @@ namespace Util.Datas.Sql.Queries { /// /// 列名,范例:t => new object[] { t.A, t.B } /// 别名 - ISqlQuery Select( Expression> columns, string alias = null ); + ISqlQuery Select( Expression> columns, string alias = null ) where TEntity : class; /// /// 设置表名 /// @@ -47,17 +47,62 @@ namespace Util.Datas.Sql.Queries { /// 架构名 ISqlQuery From( string table, string alias = null, string schema = null ); /// + /// 设置表名 + /// + /// 别名 + /// 架构名 + ISqlQuery From( string alias = null, string schema = null ) where TEntity : class; + /// /// And连接条件 /// /// 查询条件 ISqlQuery And( ICondition condition ); /// - /// 设置条件 + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 表别名 + ISqlQuery Where( Expression> expression, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 运算符 + /// 表别名 + ISqlQuery Where( Expression> expression, object value, Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 /// /// 列名 /// 值 /// 运算符 /// 表别名 ISqlQuery Where( string column, object value, Operator @operator = Operator.Equal, string tableAlias = null ); + /// + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 该值为true时添加查询条件,否则忽略 + /// 表别名 + ISqlQuery WhereIf( Expression> expression, bool condition, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + ISqlQuery WhereIf( Expression> expression, object value, bool condition, Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class; + /// + /// 设置查询条件 + /// + /// 列名 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + ISqlQuery WhereIf( string column, object value, bool condition, Operator @operator = Operator.Equal, string tableAlias = null ); } } diff --git a/src/Util/Datas/Sql/Queries/SqlQueryBase.cs b/src/Util/Datas/Sql/Queries/SqlQueryBase.cs index 832f7a94..4f7027f8 100644 --- a/src/Util/Datas/Sql/Queries/SqlQueryBase.cs +++ b/src/Util/Datas/Sql/Queries/SqlQueryBase.cs @@ -89,7 +89,7 @@ namespace Util.Datas.Sql.Queries { /// /// 列名 /// 别名 - public ISqlQuery Select( Expression> columns, string alias = null ) { + public ISqlQuery Select( Expression> columns, string alias = null ) where TEntity : class { GetBuilder().Select( columns, alias ); return this; } @@ -105,6 +105,16 @@ namespace Util.Datas.Sql.Queries { return this; } + /// + /// 设置表名 + /// + /// 别名 + /// 架构名 + public ISqlQuery From( string alias = null, string schema = null ) where TEntity : class { + GetBuilder().From( alias, schema ); + return this; + } + /// /// And连接条件 /// @@ -115,15 +125,76 @@ namespace Util.Datas.Sql.Queries { } /// - /// 设置条件 + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 表别名 + public ISqlQuery Where( Expression> expression, string tableAlias = null ) where TEntity : class { + GetBuilder().Where( expression, tableAlias ); + return this; + } + + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 运算符 + /// 表别名 + public ISqlQuery Where( Expression> expression, object value, + Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class { + GetBuilder().Where( expression, value, @operator, tableAlias ); + return this; + } + + /// + /// 设置查询条件 /// /// 列名 /// 值 /// 运算符 /// 表别名 - public ISqlQuery Where( string column, object value, Operator @operator = Operator.Equal,string tableAlias = null ) { + public ISqlQuery Where( string column, object value, Operator @operator = Operator.Equal, string tableAlias = null ) { GetBuilder().Where( column, value, @operator, tableAlias ); return this; } + + /// + /// 设置查询条件 + /// + /// 查询条件表达式 + /// 该值为true时添加查询条件,否则忽略 + /// 表别名 + public ISqlQuery WhereIf( Expression> expression, bool condition, string tableAlias = null ) where TEntity : class { + GetBuilder().WhereIf( expression, condition, tableAlias ); + return this; + } + + /// + /// 设置查询条件 + /// + /// 列名表达式 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + public ISqlQuery WhereIf( Expression> expression, object value, bool condition, + Operator @operator = Operator.Equal, string tableAlias = null ) where TEntity : class { + GetBuilder().WhereIf( expression, value, condition, @operator, tableAlias ); + return this; + } + + /// + /// 设置查询条件 + /// + /// 列名 + /// 值 + /// 该值为true时添加查询条件,否则忽略 + /// 运算符 + /// 表别名 + public ISqlQuery WhereIf( string column, object value, bool condition, Operator @operator = Operator.Equal, string tableAlias = null ) { + GetBuilder().WhereIf( column, value, condition, @operator, tableAlias ); + return this; + } } } diff --git a/src/Util/Helpers/Lambda.cs b/src/Util/Helpers/Lambda.cs index d99c213d..d7a6de4a 100644 --- a/src/Util/Helpers/Lambda.cs +++ b/src/Util/Helpers/Lambda.cs @@ -36,16 +36,36 @@ namespace Util.Helpers { return GetMemberExpression( ( (UnaryExpression)expression ).Operand ); case ExpressionType.MemberAccess: return (MemberExpression)expression; + case ExpressionType.Equal: + case ExpressionType.NotEqual: + case ExpressionType.GreaterThan: + case ExpressionType.LessThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.LessThanOrEqual: + return GetMemberExpression( ( (BinaryExpression)expression ).Left ); + case ExpressionType.Call: + return GetMethodCallExpressionName( expression ); } return null; } + /// + /// 获取方法调用表达式的成员名称 + /// + private static MemberExpression GetMethodCallExpressionName( Expression expression ) { + var methodCallExpression = (MethodCallExpression)expression; + var argumentExpression = methodCallExpression.Arguments.FirstOrDefault(); + if ( argumentExpression != null && argumentExpression.NodeType == ExpressionType.MemberAccess ) + return (MemberExpression)argumentExpression; + return (MemberExpression)methodCallExpression.Object; + } + #endregion #region GetName(获取成员名称) /// - /// 获取成员名称,范例:t => t.Name,返回 Name + /// 获取成员名称,范例:t => t.A.Name,返回 A.Name /// /// 表达式,范例:t => t.Name public static string GetName( Expression expression ) { @@ -96,6 +116,22 @@ namespace Util.Helpers { #endregion + #region GetLastName(获取最后一级成员名称) + + /// + /// 获取最后一级成员名称,范例:t => t.A.Name,返回 Name + /// + /// 表达式,范例:t => t.Name + public static string GetLastName( Expression expression ) { + var memberExpression = GetMemberExpression( expression ); + if( memberExpression == null ) + return string.Empty; + string result = memberExpression.ToString(); + return result.Substring( result.LastIndexOf( ".", StringComparison.Ordinal ) + 1 ); + } + + #endregion + #region GetValue(获取值) /// @@ -170,6 +206,56 @@ namespace Util.Helpers { #endregion + #region GetOperator(获取查询操作符) + + /// + /// 获取查询操作符,范例:t => t.Name == "A",返回 Operator.Equal + /// + /// 表达式,范例:t => t.Name == "A" + public static Operator? GetOperator( Expression expression ) { + if( expression == null ) + return null; + switch( expression.NodeType ) { + case ExpressionType.Lambda: + return GetOperator( ( (LambdaExpression)expression ).Body ); + case ExpressionType.Convert: + return GetOperator( ( (UnaryExpression)expression ).Operand ); + case ExpressionType.Equal: + return Operator.Equal; + case ExpressionType.NotEqual: + return Operator.NotEqual; + case ExpressionType.GreaterThan: + return Operator.Greater; + case ExpressionType.LessThan: + return Operator.Less; + case ExpressionType.GreaterThanOrEqual: + return Operator.GreaterEqual; + case ExpressionType.LessThanOrEqual: + return Operator.LessEqual; + case ExpressionType.Call: + return GetMethodCallExpressionOperator( expression ); + } + return null; + } + + /// + /// 获取方法调用表达式的值 + /// + private static Operator? GetMethodCallExpressionOperator( Expression expression ) { + var methodCallExpression = (MethodCallExpression)expression; + switch ( methodCallExpression?.Method?.Name?.ToLower() ) { + case "contains": + return Operator.Contains; + case "endswith": + return Operator.Ends; + case "startswith": + return Operator.Starts; + } + return null; + } + + #endregion + #region GetParameter(获取参数) /// diff --git a/test/Util.Datas.Tests.Integration/Dapper/SqlServer/SqlServerBuilderTest.cs b/test/Util.Datas.Tests.Integration/Dapper/SqlServer/SqlServerBuilderTest.cs index 27df2df9..0dec8de1 100644 --- a/test/Util.Datas.Tests.Integration/Dapper/SqlServer/SqlServerBuilderTest.cs +++ b/test/Util.Datas.Tests.Integration/Dapper/SqlServer/SqlServerBuilderTest.cs @@ -157,8 +157,8 @@ namespace Util.Datas.Tests.Dapper.SqlServer { /// [Fact] public void TestSelect_12() { - _builder.Select( "a As e,[b]" ).From( "c", "d" ); - Assert.Equal( $"Select [d].[a] As [e],[d].[b] {Common.Line}From [c] As [d]", _builder.ToSql() ); + _builder.Select( "t.a As e,[b],f.g", "k" ).Select( "n" ).From( "c", "d" ); + Assert.Equal( $"Select [t].[a] As [e],[k].[b],[f].[g],[d].[n] {Common.Line}From [c] As [d]", _builder.ToSql() ); } /// @@ -233,10 +233,37 @@ namespace Util.Datas.Tests.Dapper.SqlServer { /// [Fact] public void TestFrom_7() { - _builder.From( "a.b as t","e","f" ); + _builder.From( "a.b as t", "e", "f" ); Assert.Equal( $"Select * {Common.Line}From [a].[b] As [t]", _builder.ToSql() ); } + /// + /// 设置表 - 泛型实体 + /// + [Fact] + public void TestFrom_8() { + _builder.From(); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t]", _builder.ToSql() ); + } + + /// + /// 设置表 - 泛型实体 - 别名 + /// + [Fact] + public void TestFrom_9() { + _builder.From( "a" ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [a]", _builder.ToSql() ); + } + + /// + /// 设置表 - 泛型实体 - 别名 - 架构 + /// + [Fact] + public void TestFrom_10() { + _builder.From( "a", "b" ); + Assert.Equal( $"Select * {Common.Line}From [b].[Sample] As [a]", _builder.ToSql() ); + } + #endregion #region Where(设置条件) @@ -275,8 +302,209 @@ namespace Util.Datas.Tests.Dapper.SqlServer { /// [Fact] public void TestWhere_4() { - _builder.From( "Test" ).Where( "f.Name", "a", tableAlias: "d" ); - Assert.Equal( $"Select * {Common.Line}From [Test] As [t] {Common.Line}Where [f].[Name]=@_p__0", _builder.ToSql() ); + _builder.From( "Test as test", "test1", "test2" ).Where( "f.Name", "a", tableAlias: "d" ); + Assert.Equal( $"Select * {Common.Line}From [test2].[Test] As [test] {Common.Line}Where [f].[Name]=@_p__0", _builder.ToSql() ); + } + + /// + /// 设置条件 - 通过lambda设置列名 + /// + [Fact] + public void TestWhere_5() { + _builder.From().Where( t => t.Email, "a" ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[Email]=@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "a", _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置列名 - 设置表别名 + /// + [Fact] + public void TestWhere_6() { + _builder.From().Where( t => t.Email, "a", tableAlias: "d" ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [d].[Email]=@_p__0", _builder.ToSql() ); + } + + /// + /// 设置条件 - 通过lambda设置列名 - 通过From设置表别名 + /// + [Fact] + public void TestWhere_7() { + _builder.From( "k" ).Where( t => t.Email, "a" ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [k] {Common.Line}Where [k].[Email]=@_p__0", _builder.ToSql() ); + } + + /// + /// 设置条件 - Where覆盖From设置的表别名 + /// + [Fact] + public void TestWhere_8() { + _builder.From( "k" ).Where( t => t.Email, "a", tableAlias: "n" ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [k] {Common.Line}Where [n].[Email]=@_p__0", _builder.ToSql() ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - 相等 + /// + [Fact] + public void TestWhere_9() { + _builder.From( "k" ).Where( t => t.Email == "a" ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [k] {Common.Line}Where [k].[Email]=@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "a", _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - 不相等 + /// + [Fact] + public void TestWhere_10() { + _builder.From( "k" ).Where( t => t.Email != "a" ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [k] {Common.Line}Where [k].[Email]!=@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "a", _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - 大于 + /// + [Fact] + public void TestWhere_11() { + _builder.From().Where( t => t.IntValue > 1 ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[IntValue]>@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( 1, _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - 小于 + /// + [Fact] + public void TestWhere_12() { + _builder.From().Where( t => t.IntValue < 1 ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[IntValue]<@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( 1, _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - 大于等于 + /// + [Fact] + public void TestWhere_13() { + _builder.From().Where( t => t.IntValue >= 1 ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[IntValue]>=@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( 1, _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - 小于等于 + /// + [Fact] + public void TestWhere_14() { + _builder.From().Where( t => t.IntValue <= 1 ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[IntValue]<=@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( 1, _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - Contains + /// + [Fact] + public void TestWhere_15() { + _builder.From().Where( t => t.Email.Contains( "a" ) ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[Email] Like @_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "%a%", _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - StartsWith + /// + [Fact] + public void TestWhere_16() { + _builder.From().Where( t => t.Email.StartsWith( "a" ) ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[Email] Like @_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "a%", _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置条件 - EndsWith + /// + [Fact] + public void TestWhere_17() { + _builder.From( "k" ).Where( t => t.Email.EndsWith( "a" ) ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [k] {Common.Line}Where [k].[Email] Like @_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "%a", _builder.GetParams()["@_p__0"] ); + } + + #endregion + + #region WhereIf(设置条件) + + /// + /// 设置条件 - 添加条件 + /// + [Fact] + public void TestWhereIf_1() { + _builder.From( "Test" ).WhereIf( "Name", "a", true ); + Assert.Equal( $"Select * {Common.Line}From [Test] As [t] {Common.Line}Where [t].[Name]=@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "a", _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 忽略条件 + /// + [Fact] + public void TestWhereIf_2() { + _builder.From( "Test" ).WhereIf( "Name", "a", false ); + Assert.Equal( $"Select * {Common.Line}From [Test] As [t]", _builder.ToSql() ); + Assert.Empty( _builder.GetParams() ); + } + + /// + /// 设置条件 - 通过lambda设置列名 - 添加条件 + /// + [Fact] + public void TestWhereIf_3() { + _builder.From().WhereIf( t => t.Email, "a", true ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t] {Common.Line}Where [t].[Email]=@_p__0", _builder.ToSql() ); + Assert.Single( _builder.GetParams() ); + Assert.Equal( "a", _builder.GetParams()["@_p__0"] ); + } + + /// + /// 设置条件 - 通过lambda设置列名 - 忽略条件 + /// + [Fact] + public void TestWhereIf_4() { + _builder.From().WhereIf( t => t.Email, "a", false ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [t]", _builder.ToSql() ); + Assert.Empty( _builder.GetParams() ); + } + + /// + /// 设置条件 - 通过lambda设置列名 - 添加条件 + /// + [Fact] + public void TestWhereIf_5() { + _builder.From( "k" ).WhereIf( t => t.Email == "a", true ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [k] {Common.Line}Where [k].[Email]=@_p__0", _builder.ToSql() ); + } + + /// + /// 设置条件 - 通过lambda设置列名 - 忽略条件 + /// + [Fact] + public void TestWhereIf_6() { + _builder.From( "k" ).WhereIf( t => t.Email == "a", false ); + Assert.Equal( $"Select * {Common.Line}From [Sample] As [k]", _builder.ToSql() ); } #endregion @@ -343,4 +571,4 @@ namespace Util.Datas.Tests.Dapper.SqlServer { #endregion } -} +} \ No newline at end of file diff --git a/test/Util.Tests/Datas/Sql/Conditions/GreaterConditionTest.cs b/test/Util.Tests/Datas/Sql/Conditions/GreaterConditionTest.cs new file mode 100644 index 00000000..79321016 --- /dev/null +++ b/test/Util.Tests/Datas/Sql/Conditions/GreaterConditionTest.cs @@ -0,0 +1,18 @@ +using Util.Datas.Sql.Queries.Builders.Conditions; +using Xunit; + +namespace Util.Tests.Datas.Sql.Conditions { + /// + /// Sql大于查询条件测试 + /// + public class GreaterConditionTest { + /// + /// 获取条件 + /// + [Fact] + public void Test() { + var condition = new GreaterCondition( "Age", "@Age" ); + Assert.Equal( "Age>@Age", condition.GetCondition() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Tests/Datas/Sql/Conditions/GreaterEqualConditionTest.cs b/test/Util.Tests/Datas/Sql/Conditions/GreaterEqualConditionTest.cs new file mode 100644 index 00000000..1afa5e55 --- /dev/null +++ b/test/Util.Tests/Datas/Sql/Conditions/GreaterEqualConditionTest.cs @@ -0,0 +1,18 @@ +using Util.Datas.Sql.Queries.Builders.Conditions; +using Xunit; + +namespace Util.Tests.Datas.Sql.Conditions { + /// + /// Sql大于等于查询条件测试 + /// + public class GreaterEqualConditionTest { + /// + /// 获取条件 + /// + [Fact] + public void Test() { + var condition = new GreaterEqualCondition( "Age", "@Age" ); + Assert.Equal( "Age>=@Age", condition.GetCondition() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Tests/Datas/Sql/Conditions/LessConditionTest.cs b/test/Util.Tests/Datas/Sql/Conditions/LessConditionTest.cs new file mode 100644 index 00000000..4e31c518 --- /dev/null +++ b/test/Util.Tests/Datas/Sql/Conditions/LessConditionTest.cs @@ -0,0 +1,18 @@ +using Util.Datas.Sql.Queries.Builders.Conditions; +using Xunit; + +namespace Util.Tests.Datas.Sql.Conditions { + /// + /// Sql小于查询条件测试 + /// + public class LessConditionTest { + /// + /// 获取条件 + /// + [Fact] + public void Test() { + var condition = new LessCondition( "Age", "@Age" ); + Assert.Equal( "Age<@Age", condition.GetCondition() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Tests/Datas/Sql/Conditions/LessEqualConditionTest.cs b/test/Util.Tests/Datas/Sql/Conditions/LessEqualConditionTest.cs new file mode 100644 index 00000000..b263a19f --- /dev/null +++ b/test/Util.Tests/Datas/Sql/Conditions/LessEqualConditionTest.cs @@ -0,0 +1,18 @@ +using Util.Datas.Sql.Queries.Builders.Conditions; +using Xunit; + +namespace Util.Tests.Datas.Sql.Conditions { + /// + /// Sql小于等于查询条件测试 + /// + public class LessEqualConditionTest { + /// + /// 获取条件 + /// + [Fact] + public void Test() { + var condition = new LessEqualCondition( "Age", "@Age" ); + Assert.Equal( "Age<=@Age", condition.GetCondition() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Tests/Datas/Sql/Conditions/LikeConditionTest.cs b/test/Util.Tests/Datas/Sql/Conditions/LikeConditionTest.cs new file mode 100644 index 00000000..12279f05 --- /dev/null +++ b/test/Util.Tests/Datas/Sql/Conditions/LikeConditionTest.cs @@ -0,0 +1,18 @@ +using Util.Datas.Sql.Queries.Builders.Conditions; +using Xunit; + +namespace Util.Tests.Datas.Sql.Conditions { + /// + /// Sql模糊查询条件测试 + /// + public class LikeConditionTest { + /// + /// 获取条件 + /// + [Fact] + public void Test() { + var condition = new LikeCondition( "Name", "@Name" ); + Assert.Equal( "Name Like @Name", condition.GetCondition() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Tests/Datas/Sql/Conditions/NotEqualConditionTest.cs b/test/Util.Tests/Datas/Sql/Conditions/NotEqualConditionTest.cs new file mode 100644 index 00000000..20a6d82e --- /dev/null +++ b/test/Util.Tests/Datas/Sql/Conditions/NotEqualConditionTest.cs @@ -0,0 +1,18 @@ +using Util.Datas.Sql.Queries.Builders.Conditions; +using Xunit; + +namespace Util.Tests.Datas.Sql.Conditions { + /// + /// Sql不相等查询条件测试 + /// + public class NotEqualConditionTest { + /// + /// 获取条件 + /// + [Fact] + public void Test() { + var condition = new NotEqualCondition( "Name", "@Name" ); + Assert.Equal( "Name!=@Name", condition.GetCondition() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Tests/Helpers/LambdaTest.cs b/test/Util.Tests/Helpers/LambdaTest.cs index b3efddc6..11251f6d 100644 --- a/test/Util.Tests/Helpers/LambdaTest.cs +++ b/test/Util.Tests/Helpers/LambdaTest.cs @@ -75,6 +75,174 @@ namespace Util.Tests.Helpers { #endregion + #region GetLastName(获取最后一级成员名称) + + /// + /// 测试获取成员名称 - 返回类型为Object + /// + [Fact] + public void TestGetLastName_Object() { + Expression> expression = t => t.StringValue == "A"; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + } + + /// + /// 测试获取成员名称 - 返回类型为bool + /// + [Fact] + public void TestGetLastName_Bool() { + Assert.Empty( Lambda.GetLastName( null ) ); + + Expression> expression = t => t.StringValue == "A"; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + Expression> expression2 = t => t.Test2.IntValue == 1; + Assert.Equal( "IntValue", Lambda.GetLastName( expression2 ) ); + + Expression> expression3 = t => t.Test2.Test3.StringValue == "B"; + Assert.Equal( "StringValue", Lambda.GetLastName( expression3 ) ); + } + + /// + /// 测试获取成员名称 - 运算符 + /// + [Fact] + public void TestGetLastName_Operation() { + Expression> expression = t => t.Test2.IntValue != 1; + Assert.Equal( "IntValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.IntValue > 1; + Assert.Equal( "IntValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.IntValue < 1; + Assert.Equal( "IntValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.IntValue >= 1; + Assert.Equal( "IntValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.IntValue <= 1; + Assert.Equal( "IntValue", Lambda.GetLastName( expression ) ); + } + + /// + /// 测试获取成员名称 - 可空类型 + /// + [Fact] + public void TestGetLastName_Nullable() { + Expression> expression = t => t.NullableIntValue == 1; + Assert.Equal( "NullableIntValue", Lambda.GetLastName( expression ) ); + + expression = t => t.NullableDecimalValue == 1.5M; + Assert.Equal( "NullableDecimalValue", Lambda.GetLastName( expression ) ); + } + + /// + /// 测试获取成员名称 - 方法 + /// + [Fact] + public void TestGetLastName_Method() { + Expression> expression = t => t.StringValue.Contains( "A" ); + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.StringValue.Contains( "B" ); + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.Test3.StringValue.StartsWith( "C" ); + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + } + + /// + /// 测试获取成员名称 - 实例 + /// + [Fact] + public void TestGetLastName_Instance() { + var test = new Sample() { StringValue = "a", Test2 = new Sample2() { StringValue = "b", Test3 = new Sample3() { StringValue = "c" } } }; + + Expression> expression = () => test.StringValue; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + Expression> expression2 = () => test.Test2.StringValue; + Assert.Equal( "StringValue", Lambda.GetLastName( expression2 ) ); + + Expression> expression3 = () => test.Test2.Test3.StringValue; + Assert.Equal( "StringValue", Lambda.GetLastName( expression3 ) ); + } + + /// + /// 测试获取成员名称 - 复杂类型 + /// + [Fact] + public void TestGetLastName_Complex() { + var test = new Sample() { StringValue = "a", Test2 = new Sample2() { StringValue = "b" } }; + + Expression> expression = t => t.StringValue == test.StringValue; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + Expression> expression2 = t => t.StringValue == test.Test2.StringValue; + Assert.Equal( "StringValue", Lambda.GetLastName( expression2 ) ); + + Expression> expression3 = t => t.StringValue.Contains( test.StringValue ); + Assert.Equal( "StringValue", Lambda.GetLastName( expression3 ) ); + Expression> expression4 = t => t.StringValue.Contains( test.Test2.StringValue ); + Assert.Equal( "StringValue", Lambda.GetLastName( expression4 ) ); + } + + /// + /// 测试获取成员名称 - 枚举 + /// + [Fact] + public void TestGetLastName_Enum() { + var test1 = new Sample { NullableEnumValue = EnumSample.C }; + + Expression> expression = test => test.EnumValue == EnumSample.D; + Assert.Equal( "EnumValue", Lambda.GetLastName( expression ) ); + + expression = test => test.EnumValue == test1.NullableEnumValue; + Assert.Equal( "EnumValue", Lambda.GetLastName( expression ) ); + + expression = test => test.NullableEnumValue == EnumSample.E; + Assert.Equal( "NullableEnumValue", Lambda.GetLastName( expression ) ); + + expression = test => test.NullableEnumValue == test1.NullableEnumValue; + Assert.Equal( "NullableEnumValue", Lambda.GetLastName( expression ) ); + + test1.NullableEnumValue = null; + expression = test => test.NullableEnumValue == test1.NullableEnumValue; + Assert.Equal( "NullableEnumValue", Lambda.GetLastName( expression ) ); + } + + /// + /// 测试获取成员名称 - 集合 + /// + [Fact] + public void TestGetLastName_List() { + var list = new List { "a", "b" }; + Expression> expression = t => list.Contains( t.Test2.StringValue ); + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + } + + /// + /// 测试获取成员名称 - 静态成员 + /// + [Fact] + public void TestGetLastName_Static() { + Expression> expression = t => t.StringValue == Sample.StaticString; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + expression = t => t.StringValue == Sample.StaticSample.StringValue; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.StringValue == Sample.StaticString; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.StringValue == Sample.StaticSample.StringValue; + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + + expression = t => t.Test2.StringValue.Contains( Sample.StaticSample.StringValue ); + Assert.Equal( "StringValue", Lambda.GetLastName( expression ) ); + } + + #endregion + #region GetValue(获取成员值) /// @@ -243,6 +411,153 @@ namespace Util.Tests.Helpers { #endregion + #region GetOperator(获取查询操作符) + + /// + /// 获取查询操作符 - 返回类型为Object + /// + [Fact] + public void TestGetOperator_Object() { + Expression> expression = t => t.StringValue == "A"; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + } + + /// + /// 获取查询操作符 - 返回类型为bool + /// + [Fact] + public void TestGetOperator() { + Assert.Null( Lambda.GetOperator( null ) ); + + Expression> expression = t => t.StringValue == "A"; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + Expression> expression2 = t => t.Test2.IntValue == 1; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression2 ) ); + + Expression> expression3 = t => t.Test2.Test3.StringValue == "B"; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression3 ) ); + } + + /// + /// 获取查询操作符 - 运算符 + /// + [Fact] + public void TestGetOperator_Operation() { + Expression> expression = t => t.Test2.IntValue != 1; + Assert.Equal( Operator.NotEqual, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.IntValue > 1; + Assert.Equal( Operator.Greater, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.IntValue < 1; + Assert.Equal( Operator.Less, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.IntValue >= 1; + Assert.Equal( Operator.GreaterEqual, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.IntValue <= 1; + Assert.Equal( Operator.LessEqual, Lambda.GetOperator( expression ) ); + } + + /// + /// 获取查询操作符 - 可空类型 + /// + [Fact] + public void TestGetOperator_Nullable() { + Expression> expression = t => t.NullableIntValue == 1; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = t => t.NullableDecimalValue == 1.5M; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + } + + /// + /// 获取查询操作符 - 方法 + /// + [Fact] + public void TestGetOperator_Method() { + Expression> expression = t => t.StringValue.Contains( "A" ); + Assert.Equal( Operator.Contains, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.StringValue.EndsWith( "B" ); + Assert.Equal( Operator.Ends, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.Test3.StringValue.StartsWith( "C" ); + Assert.Equal( Operator.Starts, Lambda.GetOperator( expression ) ); + } + + /// + /// 获取查询操作符 - 复杂类型 + /// + [Fact] + public void TestGetOperator_Complex() { + var test = new Sample() { StringValue = "a", Test2 = new Sample2() { StringValue = "b" } }; + + Expression> expression = t => t.StringValue == test.StringValue; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + Expression> expression2 = t => t.StringValue != test.Test2.StringValue; + Assert.Equal( Operator.NotEqual, Lambda.GetOperator( expression2 ) ); + + Expression> expression3 = t => t.StringValue.Contains( test.StringValue ); + Assert.Equal( Operator.Contains, Lambda.GetOperator( expression3 ) ); + Expression> expression4 = t => t.StringValue.EndsWith( test.Test2.StringValue ); + Assert.Equal( Operator.Ends, Lambda.GetOperator( expression4 ) ); + } + + /// + /// 获取查询操作符 - 枚举 + /// + [Fact] + public void TestGetOperator_Enum() { + var test1 = new Sample { NullableEnumValue = EnumSample.C }; + + Expression> expression = test => test.EnumValue == EnumSample.D; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = test => test.EnumValue == test1.NullableEnumValue; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = test => test.NullableEnumValue == EnumSample.E; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = test => test.NullableEnumValue == test1.NullableEnumValue; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + } + + /// + /// 获取查询操作符 - 集合 + /// + [Fact] + public void TestGetOperator_List() { + var list = new List { "a", "b" }; + Expression> expression = t => list.Contains( t.StringValue ); + Assert.Equal( Operator.Contains, Lambda.GetOperator( expression ) ); + } + + /// + /// 获取查询操作符 - 静态成员 + /// + [Fact] + public void TestGetOperator_Static() { + Expression> expression = t => t.StringValue == Sample.StaticString; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = t => t.StringValue == Sample.StaticSample.StringValue; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.StringValue == Sample.StaticString; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.StringValue == Sample.StaticSample.StringValue; + Assert.Equal( Operator.Equal, Lambda.GetOperator( expression ) ); + + expression = t => t.Test2.StringValue.Contains( Sample.StaticSample.StringValue ); + Assert.Equal( Operator.Contains, Lambda.GetOperator( expression ) ); + } + + #endregion + #region GetParameter(获取参数) ///