diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index a74ab260..b415c3d0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -379,6 +379,11 @@ WHERE ROWNUM < 11"; var dkkdksdjgj22 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.Subtract(dt1970).TotalSeconds).ToSql(); + var xxxhzytuple = g.sqlserver.Select() + .Where(a => a.Item1.Code == "xxx" && a.Item2.OptionsEntity03 == true) + .ToSql(); + + var xxxkdkd = g.oracle.Select() .InnerJoin((a,b) => true) .Where((a,b) => (DateTime.Now - a.EditTime).TotalMinutes > 100) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index a35f2516..b4839cfb 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -9,7 +9,9 @@ using System.Threading.Tasks; namespace FreeSql { - public partial interface ISelect0 + public partial interface ISelect0 { } + + public partial interface ISelect0 : ISelect0 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index b576af5b..1b57b273 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -54,6 +54,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression, bool>> exp); ISelectGrouping> GroupBy(Expression> exp); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6952905d..44df11aa 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1664,6 +1664,39 @@ namespace FreeSql.Internal } } + internal class ReplaceHzyTupleToMultiParam : ExpressionVisitor + { + private List tables; + private ParameterExpression[] parameters; + public LambdaExpression Modify(LambdaExpression lambda, List tables) + { + this.tables = tables; + parameters = tables.Select(a => a.Parameter ?? Expression.Parameter(a.Table.Type, a.Alias)).ToArray(); + var exp = Visit(lambda.Body); + return Expression.Lambda(exp, parameters); + } + + protected override Expression VisitMember(MemberExpression node) + { + int widx; + if (node.Expression?.NodeType == ExpressionType.MemberAccess) + { + var parent = node.Expression as MemberExpression; + if (parent.Expression?.NodeType == ExpressionType.Parameter && + parent.Expression.Type.Name.StartsWith("NativeTuple`") == true && + int.TryParse(parent.Member.Name.Replace("Item", ""), out widx) && widx > 0 && widx <= tables.Count) + return Expression.Property(parameters[widx - 1], node.Member.Name); + } + + if (node.Expression?.NodeType == ExpressionType.Parameter && + node.Expression.Type.Name.StartsWith("NativeTuple`") == true && + int.TryParse(node.Member.Name.Replace("Item", ""), out widx) && widx > 0 && widx <= tables.Count) + return parameters[widx - 1]; + + return base.VisitMember(node); + } + } + public string formatSql(object obj, Type mapType, ColumnInfo mapColumn, List dbParams) { //参数化设置,日后优化 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index ca3712fd..bafaf7be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -60,7 +60,7 @@ namespace FreeSql.Internal.CommonProvider #endif _includeInfo.Clear(); _selectExpression = null; - _whereGlobalFilter.Clear(); + _whereGlobalFilter?.Clear(); } public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection lambParms) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 08d0d55c..3c65f7b7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -178,6 +178,14 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } + ISelect ISelect.Where(Expression, bool>> exp) + { + if (exp == null) return this.Where(null); + var exp2 = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + for (var a = 0; a < exp2.Parameters.Count; a++) _tables[a].Parameter = exp2.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp2, null, _whereGlobalFilter, _params)); + } + bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any();