diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 8a322d57..5b9294b5 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -149,20 +149,20 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion -var testitems = new[] -{ - new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, - new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, - new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, - new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, - new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, - new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, - new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, - new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } -}; -var sqlatb = fsql.Insert(testitems).NoneParameter(); -var sqlat = sqlatb.ToSql(); -var sqlatr = sqlatb.ExecuteAffrows(); + var testitems = new[] + { + new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, + new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, + new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, + new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, + new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, + new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, + new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } + }; + var sqlatb = fsql.Insert(testitems).NoneParameter(); + var sqlat = sqlatb.ToSql(); + var sqlatr = sqlatb.ExecuteAffrows(); var sqlatc = fsql.Delete().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1"))); var sqlatca = sqlatc.ToSql(); diff --git a/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs b/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs index 250bae5c..f71d7ad5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs @@ -46,5 +46,112 @@ namespace FreeSql.Tests.Internal Assert.Equal("p", ps2[0].ParameterName); Assert.Equal(typeof(SqlParameter), ps2[0].GetType()); } + + [Fact] + public void TestReplaceSqlConstString() + { + var dict = new Dictionary(); + string sql1 = "", sql2 = "", sql3 = ""; + + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202201"" SET ""msg"" = 'msg01', ""createtime"" = '2022-01-01 13:00:11' +WHERE (""id"" = '6252a2e6-5df3-bb10-00c1-bda60c4053fe')", dict); + Assert.Equal(3, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"INSERT INTO ""as_table_log_202201""(""id"", ""msg"", ""createtime"") VALUES('6252a2e6-5df3-bb10-00c1-bda60c4053fe', 'msg01', '2022-01-01 13:00:11'), ('6252a2e6-5df3-bb10-00c1-bda773467785', 'msg02', '2022-01-02 14:00:12')", dict); + Assert.Equal(6, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"DELETE FROM ""as_table_log_202205"" WHERE (""id"" = @exp_0 AND ""createtime"" between '2022-03-01 00:00:00' and '2022-05-01 00:00:00')", dict); + Assert.Equal(2, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202202"" SET ""msg"" = CASE ""id"" +WHEN '6252a2e6-5df3-bb10-00c1-bda818f4b93f' THEN 'msg03' +WHEN '6252a2e6-5df3-bb10-00c1-bda95dbadefd' THEN 'msg04' END, ""createtime"" = CASE ""id"" +WHEN '6252a2e6-5df3-bb10-00c1-bda818f4b93f' THEN '2022-02-02 15:00:13' +WHEN '6252a2e6-5df3-bb10-00c1-bda95dbadefd' THEN '2022-02-08 15:00:13' END +WHERE (""id"" IN ('6252a2e6-5df3-bb10-00c1-bda818f4b93f','6252a2e6-5df3-bb10-00c1-bda95dbadefd'))", dict); + Assert.Equal(6, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202207"" SET ""msg"" = 'msg07', ""createtime"" = '2022-07-01 00:00:00' +WHERE (""id"" = '6252a2e6-5df3-bb10-00c1-bdad01a608fb')", dict); + Assert.Equal(3, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202207"" SET ""msg"" = 'newmsg' +WHERE (""id"" = 'acc5df07-11a5-45b5-8af1-7b1ffac19f68')", dict); + Assert.Equal(2, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202203"" SET ""msg"" = 'newmsg' +WHERE (""id"" = '29bf2df7-3dfc-4005-a2e3-0421e50b2910') AND (""createtime"" between '2022-03-01 00:00:00' and '2022-05-01 00:00:00')", dict); + Assert.Equal(4, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202203"" SET ""msg"" = 'newmsg' +WHERE (""id"" = '4c9b5b32-49b2-44ee-beee-1e399e86b933') AND (""createtime"" > '2022-03-01 00:00:00' AND ""createtime"" < '2022-05-01 00:00:00')", dict); + Assert.Equal(4, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202201"" SET ""msg"" = 'newmsg' +WHERE (""id"" = '15d2a84f-bd72-4d73-8ad1-466ba8beea60') AND (""createtime"" < '2022-05-01 00:00:00')", dict); + Assert.Equal(3, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + + dict.Clear(); + sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202204"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb + +UNION ALL + +SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202203"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb + +UNION ALL + +SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202202"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb + +UNION ALL + +SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime"" +FROM ""as_table_log_202201"" a +WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb", dict); + Assert.Equal(1, dict.Count); + sql3 = sql2; + dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList(); + Assert.Equal(sql1, sql3); + } } } diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index 2c27feca..3680ec84 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -209,14 +209,14 @@ namespace FreeSql.DataAnnotations cn = columnName.Replace("[", "\\[").Replace("]", "\\]").Replace(".", "\\."); return new[] { - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and\s+)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), - new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and\s+)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase), + //new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase), new Regex($@"({cn}\s*(<|<=|>|>=|=)\s*)(datetime|cdate|to_date)\(({quoteParameterName}[\w_]+)\)", RegexOptions.IgnoreCase), new Regex($@"({cn}\s*(<|<=|>|>=|=)(\s*))to_timestamp\(({quoteParameterName}[\w_]+)\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase), @@ -228,13 +228,13 @@ namespace FreeSql.DataAnnotations new Regex($@"({cn}\s*(between)\s+{quoteParameterName}[\w_]+\s+and(\s+))({quoteParameterName}[^w_]+)::(datetime|timestamp)", RegexOptions.IgnoreCase), - new Regex($@"{cn}\s*between\s*'([^']+)'\s*and\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*between\s*'([^']+)'\s*and\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用 new Regex($@"{cn}\s*between\s*{quoteParameterName}([\w_]+)\s*and\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), - new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'\s*and\s*{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'\s*and\s*{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用 new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)\s*and\s*{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), - new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), + new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用 new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase), }; }); @@ -256,44 +256,53 @@ namespace FreeSql.DataAnnotations public string[] GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils) { if (string.IsNullOrWhiteSpace(sqlWhere)) return AllTables; + var dictParams = new Dictionary(); + var newSqlWhere = Utils.ReplaceSqlConstString(sqlWhere, dictParams); + var tsqlWhere = Utils.ParseSqlWhereLevel1(sqlWhere); + var quoteParameterName = commonUtils.QuoteParamterName(""); var quoteParameterNameCharArray = quoteParameterName.ToCharArray(); var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name); var regs = GetRegSqlWhereDateTimes($"{(string.IsNullOrWhiteSpace(tb.Alias) ? "" : $"{tb.Alias}.")}{commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name)}", quoteParameterName); - for (var a = 0; a < 16; a++) sqlWhere = regs[a].Replace(sqlWhere, "$1$4"); + for (var a = 0; a < 8; a++) newSqlWhere = regs[a].Replace(newSqlWhere, "$1$4"); - var m = regs[16].Match(sqlWhere); - if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value); - m = m = regs[18].Match(sqlWhere); - if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value)); - m = regs[20].Match(sqlWhere); - if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value)); + //var m = regs[8].Match(newSqlWhere); + //if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value); + //m = m = regs[10].Match(newSqlWhere); + //if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value)); + //m = regs[12].Match(newSqlWhere); + //if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value)); - m = m = regs[17].Match(sqlWhere); + var m = regs[9].Match(newSqlWhere); if (m.Success) { - var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); - var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault(); + var val1 = LocalGetParamValue(m.Groups[1].Value); + var val2 = LocalGetParamValue(m.Groups[2].Value); if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return GetTableNamesByColumnValueRange(val1, val2); } - m = regs[19].Match(sqlWhere); + m = regs[11].Match(newSqlWhere); if (m.Success) { - var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); - var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault(); + var val1 = LocalGetParamValue(m.Groups[2].Value); + var val2 = LocalGetParamValue(m.Groups[4].Value); if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(val1), ParseColumnValue(val2)); } - m = regs[21].Match(sqlWhere); + m = regs[13].Match(newSqlWhere); if (m.Success) { - var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault(); + var val1 = LocalGetParamValue(m.Groups[2].Value); if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1)); } return AllTables; + object LocalGetParamValue(string paramName) + { + if (dictParams.TryGetValue(quoteParameterName + paramName, out var trydictVal)) return trydictVal; + return dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault()?.Value; + } string[] LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2) { switch (opt1) @@ -317,7 +326,7 @@ namespace FreeSql.DataAnnotations break; case ">": case ">=": - if (opt1 == ">") val1 = val1.AddSeconds(1); + if (opt1 == ">") val1 = val1.AddSeconds(1); switch (opt2) { case "<": diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index e12b00d6..6cff4587 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -572,6 +572,7 @@ namespace FreeSql.Internal.CommonProvider public IInsert AsType(Type entityType) { if (entityType == typeof(object)) throw new Exception("IInsert.AsType 参数不支持指定为 object"); + if (entityType == typeof(T1)) return this; if (entityType == _table.Type) return this; var newtb = _commonUtils.GetTableByEntity(entityType); _table = newtb ?? throw new Exception("IInsert.AsType 参数错误,请传入正确的实体类型"); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c8b513b2..13cf5235 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -2267,5 +2267,162 @@ namespace FreeSql.Internal name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_"); return char.IsLetter(name, 0) ? name : string.Concat("_", name); } + + public static string ReplaceSqlConstString(string sql, Dictionary parms) + { + var nsb = new StringBuilder(); + var sidx = 0; + var pidx = 0; + while (sidx < sql.Length) + { + var chr = sql[sidx++]; + if (chr != '\'') + { + nsb.Append(chr); + continue; + } + var startIdx = sidx; + var startLength = 0; + while (sidx < sql.Length) + { + var chrb = sql[sidx++]; + if (chrb != '\'') + { + startLength++; + continue; + } + if (sidx < sql.Length && sql[sidx] == '\'') + { + startLength += 2; + continue; + } + break; + } + if (startLength > 0) + { + var pvalue = sql.Substring(startIdx, startLength).Replace("''", "'"); + var pname = parms.Where(a => a.Value == pvalue).Select(a => a.Key).FirstOrDefault(); + if (string.IsNullOrEmpty(pname)) + { + while (true) + { + pidx++; + pname = $"@p{pidx}"; + if (parms.ContainsKey(pname) == false) break; + } + } + nsb.Append(pname); + if (parms.ContainsKey(pname) == false) parms.Add(pname, pvalue); + } + } + return nsb.ToString(); + } + + internal static string ParseSqlWhereLevel1(string sql) + { + var dictParms = new Dictionary(); + var rawsql = ReplaceSqlConstString(sql, dictParms).Trim(); + sql = Regex.Replace(rawsql, @"[\r\n\t]", " "); + var remidx = sql.IndexOf("WHERE "); + if (remidx != -1) sql = sql.Substring(remidx + 6); + + var sidx = 0; + var ltcou = 0; + var ltidxStack = new Stack(); + while (sidx < sql.Length) + { + var chr = sql[sidx++]; + if (chr == '(') + { + ltcou++; + ltidxStack.Push(sidx - 1); + } + if (chr == ')') + { + ltcou--; + var ltidx = ltidxStack.Pop(); + if (ltidx == 0 && sidx == sql.Length - 1) + break; + var sqlLeft = ltidx == 0 ? "" : sql.Remove(ltidx); + var sqlMid = sql.Substring(ltidx, sidx - ltidx); + var sqlMidNew = ""; + var sqlRight = sidx == sql.Length - 1 ? "" : sql.Substring(sidx + 1); + var mLeft = Regex.Match(sqlLeft, @" (and|or|not)\s*$", RegexOptions.IgnoreCase); + if (mLeft.Success) + { + switch (mLeft.Groups[1].Value) + { + case "and": + sqlMidNew = sqlMid.Substring(1, sqlMid.Length - 2); + break; + case "or": + break; + case "not": + break; + } + } + sidx -= sqlMid.Length - sqlMidNew.Length; + sql = $"{sqlLeft}{sqlMidNew}{sqlRight}"; + } + } + return sql; + } + + static string ParseSqlWhereLevel12(string sql) + { + var dictParms = new Dictionary(); + var rawsql = ReplaceSqlConstString(sql, dictParms); + sql = Regex.Replace(rawsql, @"[\r\n\t]", " "); + var remidx = sql.IndexOf("WHERE "); + if (remidx != -1) sql = sql.Substring(remidx + 6); + + Dictionary dicSqlParts = new Dictionary(); + var nsb = new StringBuilder(); + var swliRoot = new SqlWhereLogicInfo(); + var swliCurrent = swliRoot; + + LocalParseSqlWhere(sql); + return nsb.ToString(); + + void LocalParseSqlWhere(string sqlPart) + { + var sidx = 0; + var ltcou = 0; + var ltidxStack = new Stack(); + while (sidx < sqlPart.Length) + { + var chr = sqlPart[sidx++]; + if (chr == '(') + { + ltcou++; + ltidxStack.Push(sidx - 1); + //swliCurrent.Filters.Add() + } + if (chr == ')') + { + ltcou--; + var ltidx = ltidxStack.Pop(); + var pvalue = sqlPart.Substring(ltidx, sidx - ltidx); + break; + //var pname = $"@p_{Guid.NewGuid().ToString("N")}"; + //dicSqlParts.Add(pname, pvalue); + //LocalParseSqlWhere(sqlPart); + //var ltsql = sqlPart.Substring(Math.Max(0, ltidx - 5), ltidx); + //if (Regex.IsMatch(ltsql, @"(and|or|not)$")) + // ltsb.Last().Append("1=1"); + } + } + } + } + + class SqlWhereLogicInfo + { + public string Field { get; set; } + public string Operator { get; set; } + public object Value { get; set; } + + public DynamicFilterLogic Logic { get; set; } + public List Filters { get; set; } + } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index d069b5bf..8eb4d26a 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Dameng.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs index 4d45fb34..10b07f3c 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Firebird.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs index b54366b0..170653d9 100644 --- a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.GBase.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs index 6a4fd4a4..a529cf51 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.KingbaseES .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index 46fc44d6..85769c95 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.MySql.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index abf627c7..0f363b68 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Odbc.Dameng .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs index 7eaf2fee..34b6b4ea 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.Odbc.KingbaseES .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index 822fb089..6feac813 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -36,6 +36,7 @@ namespace FreeSql.Odbc.MySql .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index 731ad1c7..750ec905 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Odbc.Oracle .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index 8f438e22..e6bdc6a4 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.Odbc.PostgreSQL .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index 0132502c..064eccb4 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -66,6 +66,7 @@ namespace FreeSql.Odbc.SqlServer .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index f569f89a..00c611ea 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.Oracle.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index 6d5a6291..4096e713 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.PostgreSQL.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs index 47a7f022..e254523f 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -62,6 +62,7 @@ namespace FreeSql.ShenTong.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index f672ded9..159c650b 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -66,6 +66,7 @@ namespace FreeSql.SqlServer.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._table = _table; var sql = insert.ToSql(); if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index b6b4422e..bb2836a2 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.Sqlite.Curd .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._noneParameterFlag = flagInsert ? "c" : "cu"; insert._source = data; + insert._table = _table; string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql();