- 优化 HzyTuple 子查询解析;

This commit is contained in:
2881099 2020-12-25 16:03:33 +08:00
parent 89fa0dc9f6
commit 119b8f0ec0
3 changed files with 53 additions and 9 deletions

View File

@ -512,5 +512,14 @@
<param name="that"></param>
<returns></returns>
</member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members>
</doc>

View File

@ -135,9 +135,29 @@ namespace FreeSql.Tests.SqlServerExpression
w.UserName,
µ±Ç°½ÇÉ« = string.Join(",", repo.Orm
.Select<StringJoin02UserRole, StringJoin02Role>()
.LeftJoin((b, c) => b.RoleId == c.Id)
.Where((b, c) => b.UserId == w.Id)
.ToList((b, c) => c.RoleName))
.LeftJoin((a, c) => a.RoleId == c.Id)
.Where((a, c) => a.UserId == w.Id)
.ToList((a, c) => c.RoleName))
});
Assert.Equal(2, result.Count);
Assert.Equal(users[0].Id, result[0].Id);
Assert.Equal("user01", result[0].UserName);
Assert.Equal("role01,role02,role03", result[0].µ±Ç°½ÇÉ«);
Assert.Equal(users[1].Id, result[1].Id);
Assert.Equal("user02", result[1].UserName);
Assert.Equal("role01,role03", result[1].µ±Ç°½ÇÉ«);
result = repo.Select.ToList(w =>
new
{
w.Id,
w.UserName,
µ±Ç°½ÇÉ« = string.Join(",", repo.Orm
.Select<StringJoin02UserRole, StringJoin02Role>()
.LeftJoin(b => b.t1.RoleId == b.t2.Id)
.Where(b => b.t1.UserId == w.Id)
.ToList(b => b.t2.RoleName))
});
Assert.Equal(2, result.Count);
Assert.Equal(users[0].Id, result[0].Id);

View File

@ -1053,8 +1053,17 @@ namespace FreeSql.Internal
fsqltable1SetAlias = true;
var argExpLambda = argExp as LambdaExpression;
var fsqlTypeGenericArgs = fsqlType.GetGenericArguments();
for (var gai = 0; gai < fsqlTypeGenericArgs.Length && gai < argExpLambda.Parameters.Count; gai++)
fsqltables[gai].Alias = argExpLambda.Parameters[gai].Name;
if (argExpLambda.Parameters.Count == 1 && argExpLambda.Parameters[0].Type.FullName.StartsWith("FreeSql.Internal.Model.HzyTuple`"))
{
for (var gai = 0; gai < fsqlTypeGenericArgs.Length; gai++)
fsqltables[gai].Alias = "ht" + (gai + 1);
}
else
{
for (var gai = 0; gai < fsqlTypeGenericArgs.Length && gai < argExpLambda.Parameters.Count; gai++)
fsqltables[gai].Alias = argExpLambda.Parameters[gai].Name;
}
}
}
args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke();
@ -1249,7 +1258,10 @@ namespace FreeSql.Internal
tscClone1.subSelect001 = fsql as Select0Provider; //#405 Oracle within group(order by ..)
tscClone1.isDisableDiyParse = false;
tscClone1._tables = fsqltables;
var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone1)})" })?.ToString();
var exp3Args0 = (exp3.Arguments.FirstOrDefault() as UnaryExpression)?.Operand as LambdaExpression;
if (exp3Args0.Parameters.Count == 1 && exp3Args0.Parameters[0].Type.FullName.StartsWith("FreeSql.Internal.Model.HzyTuple`"))
exp3Args0 = new ReplaceHzyTupleToMultiParam().Modify(exp3Args0, fsqltables);
var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3Args0, tscClone1)})" })?.ToString();
if (string.IsNullOrEmpty(sqlSum) == false)
return $"({sqlSum.Replace(" \r\n", " \r\n ")})";
break;
@ -1260,7 +1272,10 @@ namespace FreeSql.Internal
tscClone2.subSelect001 = fsql as Select0Provider; //#405 Oracle within group(order by ..)
tscClone2.isDisableDiyParse = false;
tscClone2._tables = fsqltables;
var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone2) })?.ToString();
var exp3Args02 = (exp3.Arguments.FirstOrDefault() as UnaryExpression)?.Operand as LambdaExpression;
if (exp3Args02.Parameters.Count == 1 && exp3Args02.Parameters[0].Type.FullName.StartsWith("FreeSql.Internal.Model.HzyTuple`"))
exp3Args02 = new ReplaceHzyTupleToMultiParam().Modify(exp3Args02, fsqltables);
var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3Args02, tscClone2) })?.ToString();
if (string.IsNullOrEmpty(sqlFirst) == false)
return $"({sqlFirst.Replace(" \r\n", " \r\n ")})";
break;
@ -1794,8 +1809,8 @@ namespace FreeSql.Internal
private ParameterExpression[] parameters;
public LambdaExpression Modify(LambdaExpression lambda, List<SelectTableInfo> tables)
{
this.tables = tables;
parameters = tables.Select(a => a.Parameter ?? Expression.Parameter(a.Table.Type, a.Alias)).ToArray();
this.tables = tables.Where(a => a.Type != SelectTableInfoType.Parent).ToList();
parameters = this.tables.Select(a => a.Parameter ?? Expression.Parameter(a.Table.Type, a.Alias)).ToArray();
var exp = Visit(lambda.Body);
return Expression.Lambda(exp, parameters);
}