mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 10:42:52 +08:00
- 处理 PgArrayToMany AsSelect 子查询 #1145
This commit is contained in:
parent
50a8d979a5
commit
a50c14e77a
@ -862,6 +862,12 @@ namespace FreeSql
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var atms = navs.Where(a => a.Item1.RefType == TableRefType.PgArrayToMany).ToList();
|
||||||
|
if (atms.Any())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (dbset == rootDbSet)
|
if (dbset == rootDbSet)
|
||||||
{
|
{
|
||||||
if (CanRemove(data, true) == false) return;
|
if (CanRemove(data, true) == false) return;
|
||||||
|
@ -1195,45 +1195,164 @@ namespace FreeSql.Internal
|
|||||||
if (fsql != null)
|
if (fsql != null)
|
||||||
{
|
{
|
||||||
if (asSelectParentExp != null)
|
if (asSelectParentExp != null)
|
||||||
{ //执行 AsSelect() 的关联,OneToMany,ManyToMany
|
{
|
||||||
|
//执行 AsSelect() 的关联,OneToMany,ManyToMany,PgArrayToMany
|
||||||
if (fsqltables[0].Parameter == null)
|
if (fsqltables[0].Parameter == null)
|
||||||
{
|
{
|
||||||
fsqltables[0].Alias = $"tb_{fsqltables.Count}";
|
fsqltables[0].Alias = $"tb_{fsqltables.Count}";
|
||||||
fsqltables[0].Parameter = Expression.Parameter(asSelectEntityType, fsqltables[0].Alias);
|
fsqltables[0].Parameter = Expression.Parameter(asSelectEntityType, fsqltables[0].Alias);
|
||||||
}
|
}
|
||||||
var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 =>
|
|
||||||
typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] {
|
|
||||||
typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool)))
|
|
||||||
}));
|
|
||||||
var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type);
|
var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type);
|
||||||
var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true);
|
var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true);
|
||||||
if (parm123Ref != null)
|
if (parm123Ref != null)
|
||||||
{
|
{
|
||||||
var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType);
|
if (parm123Ref.RefType == TableRefType.PgArrayToMany)
|
||||||
Expression fsqlWhereExp = null;
|
|
||||||
if (parm123Ref.RefType == TableRefType.ManyToMany)
|
|
||||||
{
|
{
|
||||||
//g.mysql.Select<Tag>().Where(a => g.mysql.Select<Song_tag>().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any());
|
var amtReftbname = ExpressionLambdaToSql(Expression.MakeMemberAccess(asSelectParentExp, parm123Tb.Properties[parm123Tb.ColumnsByPosition[0].CsName]), tsc);
|
||||||
var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType);
|
amtReftbname = amtReftbname.Substring(0, amtReftbname.Length - _common.QuoteSqlName(parm123Tb.ColumnsByPosition[0].Attribute.Name).Length - 1);
|
||||||
var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 =>
|
if (parm123Ref.RefColumns[0] == fsqltables[0].Table.Primarys[0])
|
||||||
typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] {
|
(fsql as Select0Provider)._where.Append(" AND (").Append($"{amtReftbname}.{_common.QuoteSqlName(parm123Ref.Columns[0].Attribute.Name)} @> {fsqltables[0].Alias}.{_common.QuoteSqlName(parm123Ref.RefColumns[0].Attribute.Name)}").Append(")");
|
||||||
|
else if (parm123Ref.Columns[0] == fsqltables[0].Table.Primarys[0])
|
||||||
|
(fsql as Select0Provider)._where.Append(" AND (").Append($"{amtReftbname}.{_common.QuoteSqlName(parm123Ref.RefColumns[0].Attribute.Name)} @> {fsqltables[0].Alias}.{_common.QuoteSqlName(parm123Ref.Columns[0].Attribute.Name)}").Append(")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 =>
|
||||||
|
typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] {
|
||||||
|
typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool)))
|
||||||
|
}));
|
||||||
|
var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType);
|
||||||
|
Expression fsqlWhereExp = null;
|
||||||
|
if (parm123Ref.RefType == TableRefType.ManyToMany)
|
||||||
|
{
|
||||||
|
//g.mysql.Select<Tag>().Where(a => g.mysql.Select<Song_tag>().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any());
|
||||||
|
var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType);
|
||||||
|
var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 =>
|
||||||
|
typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] {
|
||||||
typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool)))
|
typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool)))
|
||||||
}));
|
}));
|
||||||
var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 =>
|
var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 =>
|
||||||
typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) }));
|
typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) }));
|
||||||
var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 =>
|
var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 =>
|
||||||
Expression.Call(
|
Expression.Call(
|
||||||
typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3),
|
typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3),
|
||||||
Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3)))
|
Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3)))
|
||||||
));
|
));
|
||||||
var manyMainParam = tsc._tables[0].Parameter;
|
var manyMainParam = tsc._tables[0].Parameter;
|
||||||
var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__");
|
var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__");
|
||||||
Expression manySubSelectWhereExp = null;
|
Expression manySubSelectWhereExp = null;
|
||||||
|
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++)
|
||||||
|
{
|
||||||
|
var col1 = parm123Ref.MiddleColumns[mn];
|
||||||
|
var col2 = parm123Ref.Columns[mn];
|
||||||
|
var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName);
|
||||||
|
var pexp2 = Expression.Property(asSelectParentExp, col2.CsName);
|
||||||
|
if (col1.CsType != col2.CsType)
|
||||||
|
{
|
||||||
|
if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value")));
|
||||||
|
if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value")));
|
||||||
|
}
|
||||||
|
var tmpExp = Expression.Equal(pexp1, pexp2);
|
||||||
|
if (mn == 0) manySubSelectWhereExp = tmpExp;
|
||||||
|
else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp);
|
||||||
|
}
|
||||||
|
var manySubSelectExpBoy = Expression.Call(
|
||||||
|
manySubSelectAsSelectExp,
|
||||||
|
manySubSelectWhere,
|
||||||
|
Expression.Lambda(
|
||||||
|
manySubSelectWhereExp,
|
||||||
|
manySubSelectWhereParam
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Expression fsqlManyWhereExp = null;
|
||||||
|
for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++)
|
||||||
|
{
|
||||||
|
var col1 = parm123Ref.RefColumns[mn];
|
||||||
|
var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn];
|
||||||
|
var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName);
|
||||||
|
var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName);
|
||||||
|
if (col1.CsType != col2.CsType)
|
||||||
|
{
|
||||||
|
if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value")));
|
||||||
|
if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value")));
|
||||||
|
}
|
||||||
|
var tmpExp = Expression.Equal(pexp1, pexp2);
|
||||||
|
if (mn == 0) fsqlManyWhereExp = tmpExp;
|
||||||
|
else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp);
|
||||||
|
}
|
||||||
|
MethodInfo manySubSelectAggMethod = null;
|
||||||
|
switch (exp3.Method.Name) //https://github.com/dotnetcore/FreeSql/issues/362
|
||||||
|
{
|
||||||
|
case "Any":
|
||||||
|
case "Count":
|
||||||
|
fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent });
|
||||||
|
fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) });
|
||||||
|
var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString();
|
||||||
|
if (string.IsNullOrEmpty(sql2) == false)
|
||||||
|
manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace(" \r\n", " \r\n ")})"), Expression.Constant(null));
|
||||||
|
manySubSelectAggMethod = _dicExpressionLambdaToSqlAsSelectAggMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, _ => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd(exp3.Method.Name, exp3MethodName =>
|
||||||
|
typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(parm123Ref.RefMiddleEntityType), parm123Ref.RefMiddleEntityType).GetMethod(exp3MethodName, new Type[0]));
|
||||||
|
manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAggMethod);
|
||||||
|
break;
|
||||||
|
case "Sum":
|
||||||
|
case "Min":
|
||||||
|
case "Max":
|
||||||
|
case "Avg":
|
||||||
|
case "ToList":
|
||||||
|
case "ToOne":
|
||||||
|
case "First":
|
||||||
|
//解析:string.Join(",", w.Roles.AsSelect().ToList(b => b.RoleName)
|
||||||
|
var exp3Args0 = (exp3.Arguments[0] as UnaryExpression)?.Operand as LambdaExpression;
|
||||||
|
manySubSelectAggMethod = _dicSelectMethodToSql.GetOrAdd(fsqlType, fsqlType2 =>
|
||||||
|
fsqlType2.GetMethods().Where(a => a.Name == "ToSql" && a.GetParameters().Length == 2 && a.GetParameters()[1].ParameterType == typeof(FieldAliasOptions) && a.GetGenericArguments().Length == 1).FirstOrDefault());
|
||||||
|
if (manySubSelectAggMethod == null || exp3Args0 == null) throw new ArgumentException(CoreStrings.ManyToMany_AsSelect_NotSupport_Sum_Avg_etc);
|
||||||
|
manySubSelectAggMethod = manySubSelectAggMethod.MakeGenericMethod(exp3Args0.ReturnType);
|
||||||
|
var fsqls0p = fsql as Select0Provider;
|
||||||
|
var fsqls0pWhere = fsqls0p._where.ToString();
|
||||||
|
fsqls0p._where.Clear();
|
||||||
|
var fsqltablesLast = new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.InnerJoin };
|
||||||
|
fsqltables.Add(fsqltablesLast);
|
||||||
|
fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) });
|
||||||
|
fsqltablesLast.NavigateCondition = fsqls0p._where.ToString();
|
||||||
|
if (fsqltablesLast.NavigateCondition.StartsWith(" AND (")) fsqltablesLast.NavigateCondition = fsqltablesLast.NavigateCondition.Substring(6, fsqltablesLast.NavigateCondition.Length - 7);
|
||||||
|
fsqls0p._where.Clear().Append(fsqls0pWhere);
|
||||||
|
var tsc3 = tsc.CloneDisableDiyParse();
|
||||||
|
tsc3._tables = tsc._tables.ToList();
|
||||||
|
var where2 = ExpressionLambdaToSql(Expression.Lambda(manySubSelectWhereExp, manySubSelectWhereParam), tsc3);
|
||||||
|
if (string.IsNullOrEmpty(where2) == false) fsqls0p._where.Append(" AND (").Append(where2).Append(")");
|
||||||
|
|
||||||
|
switch (exp3.Method.Name)
|
||||||
|
{
|
||||||
|
case "Sum":
|
||||||
|
case "Min":
|
||||||
|
case "Max":
|
||||||
|
case "Avg":
|
||||||
|
var map = new ReadAnonymousTypeInfo();
|
||||||
|
var field = new StringBuilder();
|
||||||
|
var index = -1;
|
||||||
|
|
||||||
|
for (var a = 0; a < exp3Args0.Parameters.Count; a++) fsqls0p._tables[a].Parameter = exp3Args0.Parameters[a];
|
||||||
|
ReadAnonymousField(fsqls0p._tables, field, map, ref index, exp3Args0, null, null, null, null, null, false);
|
||||||
|
var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null;
|
||||||
|
|
||||||
|
var sql4 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({fieldSql})" })?.ToString();
|
||||||
|
asSelectBefores.Clear();
|
||||||
|
return _common.IsNull($"({sql4.Replace(" \r\n", " \r\n ")})", formatSql(exp3.Method.ReturnType.CreateInstanceGetDefaultValue(), exp3.Method.ReturnType, null, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
var sql3 = manySubSelectAggMethod.Invoke(fsql, new object[] { exp3Args0, FieldAliasOptions.AsProperty }) as string;
|
||||||
|
asSelectBefores.Clear();
|
||||||
|
return $"({sql3.Replace(" \r\n", " \r\n ")})";
|
||||||
|
}
|
||||||
|
asSelectBefores.Clear();
|
||||||
|
return ExpressionLambdaToSql(manySubSelectExpBoy, tsc);
|
||||||
|
}
|
||||||
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++)
|
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++)
|
||||||
{
|
{
|
||||||
var col1 = parm123Ref.MiddleColumns[mn];
|
var col1 = parm123Ref.RefColumns[mn];
|
||||||
var col2 = parm123Ref.Columns[mn];
|
var col2 = parm123Ref.Columns[mn];
|
||||||
var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName);
|
var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName);
|
||||||
var pexp2 = Expression.Property(asSelectParentExp, col2.CsName);
|
var pexp2 = Expression.Property(asSelectParentExp, col2.CsName);
|
||||||
if (col1.CsType != col2.CsType)
|
if (col1.CsType != col2.CsType)
|
||||||
{
|
{
|
||||||
@ -1241,116 +1360,11 @@ namespace FreeSql.Internal
|
|||||||
if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value")));
|
if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value")));
|
||||||
}
|
}
|
||||||
var tmpExp = Expression.Equal(pexp1, pexp2);
|
var tmpExp = Expression.Equal(pexp1, pexp2);
|
||||||
if (mn == 0) manySubSelectWhereExp = tmpExp;
|
if (mn == 0) fsqlWhereExp = tmpExp;
|
||||||
else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp);
|
else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp);
|
||||||
}
|
}
|
||||||
var manySubSelectExpBoy = Expression.Call(
|
fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) });
|
||||||
manySubSelectAsSelectExp,
|
|
||||||
manySubSelectWhere,
|
|
||||||
Expression.Lambda(
|
|
||||||
manySubSelectWhereExp,
|
|
||||||
manySubSelectWhereParam
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Expression fsqlManyWhereExp = null;
|
|
||||||
for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++)
|
|
||||||
{
|
|
||||||
var col1 = parm123Ref.RefColumns[mn];
|
|
||||||
var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn];
|
|
||||||
var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName);
|
|
||||||
var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName);
|
|
||||||
if (col1.CsType != col2.CsType)
|
|
||||||
{
|
|
||||||
if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value")));
|
|
||||||
if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value")));
|
|
||||||
}
|
|
||||||
var tmpExp = Expression.Equal(pexp1, pexp2);
|
|
||||||
if (mn == 0) fsqlManyWhereExp = tmpExp;
|
|
||||||
else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp);
|
|
||||||
}
|
|
||||||
MethodInfo manySubSelectAggMethod = null;
|
|
||||||
switch (exp3.Method.Name) //https://github.com/dotnetcore/FreeSql/issues/362
|
|
||||||
{
|
|
||||||
case "Any":
|
|
||||||
case "Count":
|
|
||||||
fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent });
|
|
||||||
fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) });
|
|
||||||
var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString();
|
|
||||||
if (string.IsNullOrEmpty(sql2) == false)
|
|
||||||
manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace(" \r\n", " \r\n ")})"), Expression.Constant(null));
|
|
||||||
manySubSelectAggMethod = _dicExpressionLambdaToSqlAsSelectAggMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, _ => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd(exp3.Method.Name, exp3MethodName =>
|
|
||||||
typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(parm123Ref.RefMiddleEntityType), parm123Ref.RefMiddleEntityType).GetMethod(exp3MethodName, new Type[0]));
|
|
||||||
manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAggMethod);
|
|
||||||
break;
|
|
||||||
case "Sum":
|
|
||||||
case "Min":
|
|
||||||
case "Max":
|
|
||||||
case "Avg":
|
|
||||||
case "ToList":
|
|
||||||
case "ToOne":
|
|
||||||
case "First":
|
|
||||||
//解析:string.Join(",", w.Roles.AsSelect().ToList(b => b.RoleName)
|
|
||||||
var exp3Args0 = (exp3.Arguments[0] as UnaryExpression)?.Operand as LambdaExpression;
|
|
||||||
manySubSelectAggMethod = _dicSelectMethodToSql.GetOrAdd(fsqlType, fsqlType2 =>
|
|
||||||
fsqlType2.GetMethods().Where(a => a.Name == "ToSql" && a.GetParameters().Length == 2 && a.GetParameters()[1].ParameterType == typeof(FieldAliasOptions) && a.GetGenericArguments().Length == 1).FirstOrDefault());
|
|
||||||
if (manySubSelectAggMethod == null || exp3Args0 == null) throw new ArgumentException(CoreStrings.ManyToMany_AsSelect_NotSupport_Sum_Avg_etc);
|
|
||||||
manySubSelectAggMethod = manySubSelectAggMethod.MakeGenericMethod(exp3Args0.ReturnType);
|
|
||||||
var fsqls0p = fsql as Select0Provider;
|
|
||||||
var fsqls0pWhere = fsqls0p._where.ToString();
|
|
||||||
fsqls0p._where.Clear();
|
|
||||||
var fsqltablesLast = new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.InnerJoin };
|
|
||||||
fsqltables.Add(fsqltablesLast);
|
|
||||||
fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) });
|
|
||||||
fsqltablesLast.NavigateCondition = fsqls0p._where.ToString();
|
|
||||||
if (fsqltablesLast.NavigateCondition.StartsWith(" AND (")) fsqltablesLast.NavigateCondition = fsqltablesLast.NavigateCondition.Substring(6, fsqltablesLast.NavigateCondition.Length - 7);
|
|
||||||
fsqls0p._where.Clear().Append(fsqls0pWhere);
|
|
||||||
var tsc3 = tsc.CloneDisableDiyParse();
|
|
||||||
tsc3._tables = tsc._tables.ToList();
|
|
||||||
var where2 = ExpressionLambdaToSql(Expression.Lambda(manySubSelectWhereExp, manySubSelectWhereParam), tsc3);
|
|
||||||
if (string.IsNullOrEmpty(where2) == false) fsqls0p._where.Append(" AND (").Append(where2).Append(")");
|
|
||||||
|
|
||||||
switch (exp3.Method.Name)
|
|
||||||
{
|
|
||||||
case "Sum":
|
|
||||||
case "Min":
|
|
||||||
case "Max":
|
|
||||||
case "Avg":
|
|
||||||
var map = new ReadAnonymousTypeInfo();
|
|
||||||
var field = new StringBuilder();
|
|
||||||
var index = -1;
|
|
||||||
|
|
||||||
for (var a = 0; a < exp3Args0.Parameters.Count; a++) fsqls0p._tables[a].Parameter = exp3Args0.Parameters[a];
|
|
||||||
ReadAnonymousField(fsqls0p._tables, field, map, ref index, exp3Args0, null, null, null, null, null, false);
|
|
||||||
var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null;
|
|
||||||
|
|
||||||
var sql4 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({fieldSql})" })?.ToString();
|
|
||||||
asSelectBefores.Clear();
|
|
||||||
return _common.IsNull($"({sql4.Replace(" \r\n", " \r\n ")})", formatSql(exp3.Method.ReturnType.CreateInstanceGetDefaultValue(), exp3.Method.ReturnType, null, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
var sql3 = manySubSelectAggMethod.Invoke(fsql, new object[] { exp3Args0, FieldAliasOptions.AsProperty }) as string;
|
|
||||||
asSelectBefores.Clear();
|
|
||||||
return $"({sql3.Replace(" \r\n", " \r\n ")})";
|
|
||||||
}
|
|
||||||
asSelectBefores.Clear();
|
|
||||||
return ExpressionLambdaToSql(manySubSelectExpBoy, tsc);
|
|
||||||
}
|
}
|
||||||
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++)
|
|
||||||
{
|
|
||||||
var col1 = parm123Ref.RefColumns[mn];
|
|
||||||
var col2 = parm123Ref.Columns[mn];
|
|
||||||
var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName);
|
|
||||||
var pexp2 = Expression.Property(asSelectParentExp, col2.CsName);
|
|
||||||
if (col1.CsType != col2.CsType)
|
|
||||||
{
|
|
||||||
if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value")));
|
|
||||||
if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value")));
|
|
||||||
}
|
|
||||||
var tmpExp = Expression.Equal(pexp1, pexp2);
|
|
||||||
if (mn == 0) fsqlWhereExp = tmpExp;
|
|
||||||
else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp);
|
|
||||||
}
|
|
||||||
fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asSelectBefores.Clear();
|
asSelectBefores.Clear();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user