From a50c14e77a9fb5618497fdb9e0ba2fa8917fda55 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 6 Jun 2022 13:36:18 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A4=84=E7=90=86=20PgArrayToMany=20AsSele?= =?UTF-8?q?ct=20=E5=AD=90=E6=9F=A5=E8=AF=A2=20#1145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetSync.cs | 6 + FreeSql/Internal/CommonExpression.cs | 280 ++++++++++++++------------- 2 files changed, 153 insertions(+), 133 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 94975355..cc6f8a3e 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -862,6 +862,12 @@ namespace FreeSql } } + var atms = navs.Where(a => a.Item1.RefType == TableRefType.PgArrayToMany).ToList(); + if (atms.Any()) + { + + } + if (dbset == rootDbSet) { if (CanRemove(data, true) == false) return; diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 428efb50..b7918b54 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1195,45 +1195,164 @@ namespace FreeSql.Internal if (fsql != null) { if (asSelectParentExp != null) - { //执行 AsSelect() 的关联,OneToMany,ManyToMany + { + //执行 AsSelect() 的关联,OneToMany,ManyToMany,PgArrayToMany if (fsqltables[0].Parameter == null) { fsqltables[0].Alias = $"tb_{fsqltables.Count}"; 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 parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true); if (parm123Ref != null) { - var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType); - Expression fsqlWhereExp = null; - if (parm123Ref.RefType == TableRefType.ManyToMany) + if (parm123Ref.RefType == TableRefType.PgArrayToMany) { - //g.mysql.Select().Where(a => g.mysql.Select().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[] { + var amtReftbname = ExpressionLambdaToSql(Expression.MakeMemberAccess(asSelectParentExp, parm123Tb.Properties[parm123Tb.ColumnsByPosition[0].CsName]), tsc); + amtReftbname = amtReftbname.Substring(0, amtReftbname.Length - _common.QuoteSqlName(parm123Tb.ColumnsByPosition[0].Attribute.Name).Length - 1); + if (parm123Ref.RefColumns[0] == fsqltables[0].Table.Primarys[0]) + (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().Where(a => g.mysql.Select().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))) - })); - var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); - var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - Expression.Call( - 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))) - )); - var manyMainParam = tsc._tables[0].Parameter; - var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); - Expression manySubSelectWhereExp = null; + })); + var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); + var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + Expression.Call( + 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))) + )); + var manyMainParam = tsc._tables[0].Parameter; + var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); + 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()).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.MiddleColumns[mn]; + var col1 = parm123Ref.RefColumns[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); 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"))); } var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) manySubSelectWhereExp = tmpExp; - else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); + if (mn == 0) fsqlWhereExp = tmpExp; + else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, 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()).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); + fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); } - 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();