diff --git a/SQLBuilder.UnitTest/SelectTest.cs b/SQLBuilder.UnitTest/SelectTest.cs index 6808cb8..c7415a9 100644 --- a/SQLBuilder.UnitTest/SelectTest.cs +++ b/SQLBuilder.UnitTest/SelectTest.cs @@ -2241,6 +2241,33 @@ public void Test_Select_106() Assert.AreEqual("SELECT x.* FROM Base_UserInfo x WHERE ((x.Email <> :p__1 AND x.Id > :p__2) OR x.Email = :p__3) AND x.Sex = :p__4", builder.Sql); Assert.AreEqual(4, builder.Parameters.Count); } + + /// + /// 查询107 + /// + [TestMethod] + public void Test_Select_107() + { + var builder = SqlBuilder + .Select((u, t, a, s, d, e, f) => + new { u.Id, UId = t.Id, a.Name, StudentName = s.Name, ClassName = d.Name, e.CityName, CountryName = f.Name }) + .Join((x, t) => + x.Id == t.Id) //注意此处单表多次Join所以要指明具体表别名,否则都会读取第一个表别名 + .Join((x, y) => + x.Id == y.UserId) + .LeftJoin((x, y) => + x.Id == y.AccountId) + .RightJoin((x, y) => + x.Id == y.UserId) + .InnerJoin((u, d, e) => + d.CityId == e.Id && u.Id > e.Id) + .FullJoin((x, y) => + x.CountryId == y.Id) + .Where(x => + x.Id != null); + Assert.AreEqual("SELECT u.Id,t.Id AS UId,a.Name,s.Name AS StudentName,d.Name AS ClassName,e.City_Name AS CityName,f.Name AS CountryName FROM Base_UserInfo AS u JOIN Base_UserInfo AS t ON u.Id = t.Id JOIN Base_Account AS a ON u.Id = a.UserId LEFT JOIN Base_Student AS s ON a.Id = s.AccountId RIGHT JOIN Base_Class AS d ON s.Id = d.UserId INNER JOIN Base_City AS e ON d.CityId = e.Id AND u.Id > e.Id FULL JOIN Base_Country AS f ON e.CountryId = f.Country_Id WHERE u.Id IS NOT NULL", builder.Sql); + Assert.AreEqual(0, builder.Parameters.Count); + } #endregion #region Page diff --git a/SQLBuilder/Entry/SqlBuilderCore.cs b/SQLBuilder/Entry/SqlBuilderCore.cs index 3a1ad47..a3d615d 100644 --- a/SQLBuilder/Entry/SqlBuilderCore.cs +++ b/SQLBuilder/Entry/SqlBuilderCore.cs @@ -264,7 +264,7 @@ public SqlBuilderCore Select(Expression expression = null, string sql = null, { var len = this.sqlWrapper.Length; - var tableAlias = GetExpressionAlias(expression, typeof(T)).FirstOrDefault().alias; + var tableAlias = this.GetExpressionAlias(expression, typeof(T)).FirstOrDefault().alias; if (sql == null) sql = this.Select(tableNameFunc, (typeof(T), tableAlias)); @@ -322,7 +322,7 @@ public SqlBuilderCore Select(Expression> expression = null, F public SqlBuilderCore Select(Expression> expression = null, Func tableNameFunc = null) where T2 : class { - var sql = this.Select(tableNameFunc, GetExpressionAlias(expression, typeof(T), typeof(T2))); + var sql = this.Select(tableNameFunc, this.GetExpressionAlias(expression, typeof(T), typeof(T2))); return this.Select(expression?.Body, sql, tableNameFunc); } @@ -338,7 +338,7 @@ public SqlBuilderCore Select(Expression> expr where T2 : class where T3 : class { - var sql = this.Select(tableNameFunc, GetExpressionAlias(expression, typeof(T), typeof(T2), typeof(T3))); + var sql = this.Select(tableNameFunc, this.GetExpressionAlias(expression, typeof(T), typeof(T2), typeof(T3))); return this.Select(expression?.Body, sql, tableNameFunc); } @@ -356,7 +356,7 @@ public SqlBuilderCore Select(Expression Select(Expression Select(Expression Select(Expression Select(Expression Select(Expression Select(Expression< where T9 : class where T10 : class { - var sql = this.Select(tableNameFunc, GetExpressionAlias(expression, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10))); + var sql = this.Select(tableNameFunc, this.GetExpressionAlias(expression, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10))); return this.Select(expression?.Body, sql, tableNameFunc); } #endregion #region Join + /// + /// 获取目标Join类型 + /// + /// + /// + private Type GetJoinType(params Type[] types) + { + Type type = null; + + for (int i = types.Length - 1; i >= 0; i--) + { + type = types[i]; + if (this.sqlWrapper.IsJoined(type)) + { + //倒序判断,第一个被Join后,则重置为最后一个 + if (i == 0) + type = types.Last(); + + continue; + } + } + + return type; + } + /// /// Join /// @@ -539,18 +564,16 @@ public SqlBuilderCore Join(StringBuilder sql) /// /// Join /// - /// 泛型类型2 + /// Join的实体类型 /// 表达式树 /// 连接类型 /// 表名自定义委托 /// SqlBuilderCore - public SqlBuilderCore Join(Expression> expression, string join, Func tableNameFunc = null) - where T2 : class + public SqlBuilderCore Join(Type type, Expression expression, string join, Func tableNameFunc = null) { - var type = typeof(T2); this.sqlWrapper.AddJoinType(type); - var alias = GetExpressionAlias(expression, type).Last().alias; + var alias = this.GetExpressionAlias(expression, type).Last().alias; var tableName = this.sqlWrapper.GetTableName(type); /*** @@ -572,7 +595,7 @@ public SqlBuilderCore Join(Expression> expression, stri else this.sqlWrapper.Append($"{(join.IsNullOrEmpty() ? "" : $" {join}")} JOIN {tableNameFunc(new[] { tableName, @as, tableAlias })} ON "); - SqlExpressionProvider.Join(expression.Body, this.sqlWrapper); + SqlExpressionProvider.Join(expression, this.sqlWrapper); return this; } @@ -581,56 +604,53 @@ public SqlBuilderCore Join(Expression> expression, stri /// Join /// /// 泛型类型2 - /// 泛型类型3 /// 表达式树 /// 连接类型 /// 表名自定义委托 /// SqlBuilderCore - public SqlBuilderCore Join(Expression> expression, string join, Func tableNameFunc = null) + public SqlBuilderCore Join(Expression expression, string join, Func tableNameFunc = null) where T2 : class - where T3 : class { - var type2 = typeof(T2); - var type3 = typeof(T3); - var type = type3; + var type = this.GetJoinType(typeof(T2)); - //如果T3已被Join,则选择T2 - if (this.sqlWrapper.IsJoined(type3)) - { - type = type2; - - //如果T2也已被Join,则重置为T3 - if (this.sqlWrapper.IsJoined(type2)) - type = type3; - } - - this.sqlWrapper.AddJoinType(type); - - var alias = GetExpressionAlias(expression, type).Last().alias; - var tableName = this.sqlWrapper.GetTableName(type); - - /*** - * 注释Join新增表别名逻辑,此时如果是多表查询,则要求Select方法内必须用lambda表达式显示指明每个表的别名 - * 此时每个Join内的lambda表达式形参命名可以随意命名 - * this.sqlWrapper.SetTableAlias(tableName, alias); - */ - - var tableAlias = this.sqlWrapper.GetTableAlias(tableName, alias); - - //Oracle表别名不支持AS关键字,列别名支持; - var @as = this.sqlWrapper.DatabaseType == DatabaseType.Oracle ? " " : " AS "; + return this.Join(type, expression, join, tableNameFunc); + } - if (tableAlias.IsNullOrEmpty()) - @as = ""; + /// + /// Join + /// + /// 泛型类型2 + /// 泛型类型3 + /// 表达式树 + /// 连接类型 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore Join(Expression expression, string join, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + var type = this.GetJoinType(typeof(T2), typeof(T3)); - if (tableNameFunc.IsNull()) - this.sqlWrapper.Append($"{(join.IsNullOrEmpty() ? "" : $" {join}")} JOIN {tableName}{@as}{tableAlias} ON "); - else - this.sqlWrapper.Append($"{(join.IsNullOrEmpty() ? "" : $" {join}")} JOIN {tableNameFunc(new[] { tableName, @as, tableAlias })} ON "); + return this.Join(type, expression, join, tableNameFunc); + } - SqlExpressionProvider.Join(expression.Body, this.sqlWrapper); + /// + /// Join + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 连接类型 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore Join(Expression expression, string join, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + var type = this.GetJoinType(typeof(T2), typeof(T3), typeof(T4)); - return this; + return this.Join(type, expression, join, tableNameFunc); } /// @@ -661,6 +681,53 @@ public SqlBuilderCore Join(Expression> expression, return this.Join(expression, "", tableNameFunc); } + /// + /// Join + /// + /// 泛型类型2 + /// 泛型类型3 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore Join(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "", tableNameFunc); + } + + /// + /// Join + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore Join(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "", tableNameFunc); + } + + /// + /// Join + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore Join(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "", tableNameFunc); + } + /// /// InnerJoin /// @@ -713,6 +780,53 @@ public SqlBuilderCore InnerJoin(Expression> expres return this.Join(expression, "INNER", tableNameFunc); } + /// + /// InnerJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore InnerJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "INNER", tableNameFunc); + } + + /// + /// InnerJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore InnerJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "INNER", tableNameFunc); + } + + /// + /// InnerJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore InnerJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "INNER", tableNameFunc); + } + /// /// LeftJoin /// @@ -765,6 +879,53 @@ public SqlBuilderCore LeftJoin(Expression> express return this.Join(expression, "LEFT", tableNameFunc); } + /// + /// LeftJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore LeftJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "LEFT", tableNameFunc); + } + + /// + /// LeftJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore LeftJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "LEFT", tableNameFunc); + } + + /// + /// LeftJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore LeftJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "LEFT", tableNameFunc); + } + /// /// RightJoin /// @@ -817,6 +978,53 @@ public SqlBuilderCore RightJoin(Expression> expres return this.Join(expression, "RIGHT", tableNameFunc); } + /// + /// RightJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore RightJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "RIGHT", tableNameFunc); + } + + /// + /// RightJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore RightJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "RIGHT", tableNameFunc); + } + + /// + /// RightJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore RightJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "RIGHT", tableNameFunc); + } + /// /// FullJoin /// @@ -868,6 +1076,53 @@ public SqlBuilderCore FullJoin(Expression> express { return this.Join(expression, "FULL", tableNameFunc); } + + /// + /// FullJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore FullJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "FULL", tableNameFunc); + } + + /// + /// FullJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore FullJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "FULL", tableNameFunc); + } + + /// + /// FullJoin + /// + /// 泛型类型2 + /// 泛型类型3 + /// 泛型类型4 + /// 表达式树 + /// 表名自定义委托 + /// SqlBuilderCore + public SqlBuilderCore FullJoin(Expression> expression, Func tableNameFunc = null) + where T2 : class + where T3 : class + { + return this.Join(expression, "FULL", tableNameFunc); + } #endregion #region Where diff --git a/SQLBuilder/Expressions/LambdaExpressionResolver.cs b/SQLBuilder/Expressions/LambdaExpressionResolver.cs index 2c5cc0a..b702e12 100644 --- a/SQLBuilder/Expressions/LambdaExpressionResolver.cs +++ b/SQLBuilder/Expressions/LambdaExpressionResolver.cs @@ -65,6 +65,19 @@ public override SqlWrapper Having(LambdaExpression expression, SqlWrapper sqlWra return sqlWrapper; } + + /// + /// Join + /// + /// 表达式树 + /// sql打包对象 + /// SqlWrapper + public override SqlWrapper Join(LambdaExpression expression, SqlWrapper sqlWrapper) + { + SqlExpressionProvider.Join(expression.Body, sqlWrapper); + + return sqlWrapper; + } #endregion } }