Skip to content

Commit 7c2b7ea

Browse files
committed
- 修复 InsertOrUpdateDict 异常;#1067
1 parent ecd27fb commit 7c2b7ea

File tree

21 files changed

+331
-41
lines changed

21 files changed

+331
-41
lines changed

Examples/base_entity/Program.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,20 +149,20 @@ static void Main(string[] args)
149149
BaseEntity.Initialization(fsql, () => _asyncUow.Value);
150150
#endregion
151151

152-
var testitems = new[]
153-
{
154-
new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") },
155-
new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") },
156-
new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") },
157-
new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") },
158-
new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") },
159-
new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") },
160-
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") },
161-
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") }
162-
};
163-
var sqlatb = fsql.Insert(testitems).NoneParameter();
164-
var sqlat = sqlatb.ToSql();
165-
var sqlatr = sqlatb.ExecuteAffrows();
152+
var testitems = new[]
153+
{
154+
new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") },
155+
new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") },
156+
new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") },
157+
new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") },
158+
new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") },
159+
new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") },
160+
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") },
161+
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") }
162+
};
163+
var sqlatb = fsql.Insert(testitems).NoneParameter();
164+
var sqlat = sqlatb.ToSql();
165+
var sqlatr = sqlatb.ExecuteAffrows();
166166

167167
var sqlatc = fsql.Delete<AsTableLog>().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1")));
168168
var sqlatca = sqlatc.ToSql();

FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,112 @@ public void TestGetDbParamtersByObject()
4646
Assert.Equal("p", ps2[0].ParameterName);
4747
Assert.Equal(typeof(SqlParameter), ps2[0].GetType());
4848
}
49+
50+
[Fact]
51+
public void TestReplaceSqlConstString()
52+
{
53+
var dict = new Dictionary<string, string>();
54+
string sql1 = "", sql2 = "", sql3 = "";
55+
56+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202201"" SET ""msg"" = 'msg01', ""createtime"" = '2022-01-01 13:00:11'
57+
WHERE (""id"" = '6252a2e6-5df3-bb10-00c1-bda60c4053fe')", dict);
58+
Assert.Equal(3, dict.Count);
59+
sql3 = sql2;
60+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
61+
Assert.Equal(sql1, sql3);
62+
63+
dict.Clear();
64+
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);
65+
Assert.Equal(6, dict.Count);
66+
sql3 = sql2;
67+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
68+
Assert.Equal(sql1, sql3);
69+
70+
dict.Clear();
71+
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);
72+
Assert.Equal(2, dict.Count);
73+
sql3 = sql2;
74+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
75+
Assert.Equal(sql1, sql3);
76+
77+
dict.Clear();
78+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202202"" SET ""msg"" = CASE ""id""
79+
WHEN '6252a2e6-5df3-bb10-00c1-bda818f4b93f' THEN 'msg03'
80+
WHEN '6252a2e6-5df3-bb10-00c1-bda95dbadefd' THEN 'msg04' END, ""createtime"" = CASE ""id""
81+
WHEN '6252a2e6-5df3-bb10-00c1-bda818f4b93f' THEN '2022-02-02 15:00:13'
82+
WHEN '6252a2e6-5df3-bb10-00c1-bda95dbadefd' THEN '2022-02-08 15:00:13' END
83+
WHERE (""id"" IN ('6252a2e6-5df3-bb10-00c1-bda818f4b93f','6252a2e6-5df3-bb10-00c1-bda95dbadefd'))", dict);
84+
Assert.Equal(6, dict.Count);
85+
sql3 = sql2;
86+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
87+
Assert.Equal(sql1, sql3);
88+
89+
dict.Clear();
90+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202207"" SET ""msg"" = 'msg07', ""createtime"" = '2022-07-01 00:00:00'
91+
WHERE (""id"" = '6252a2e6-5df3-bb10-00c1-bdad01a608fb')", dict);
92+
Assert.Equal(3, dict.Count);
93+
sql3 = sql2;
94+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
95+
Assert.Equal(sql1, sql3);
96+
97+
dict.Clear();
98+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202207"" SET ""msg"" = 'newmsg'
99+
WHERE (""id"" = 'acc5df07-11a5-45b5-8af1-7b1ffac19f68')", dict);
100+
Assert.Equal(2, dict.Count);
101+
sql3 = sql2;
102+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
103+
Assert.Equal(sql1, sql3);
104+
105+
dict.Clear();
106+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202203"" SET ""msg"" = 'newmsg'
107+
WHERE (""id"" = '29bf2df7-3dfc-4005-a2e3-0421e50b2910') AND (""createtime"" between '2022-03-01 00:00:00' and '2022-05-01 00:00:00')", dict);
108+
Assert.Equal(4, dict.Count);
109+
sql3 = sql2;
110+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
111+
Assert.Equal(sql1, sql3);
112+
113+
dict.Clear();
114+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202203"" SET ""msg"" = 'newmsg'
115+
WHERE (""id"" = '4c9b5b32-49b2-44ee-beee-1e399e86b933') AND (""createtime"" > '2022-03-01 00:00:00' AND ""createtime"" < '2022-05-01 00:00:00')", dict);
116+
Assert.Equal(4, dict.Count);
117+
sql3 = sql2;
118+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
119+
Assert.Equal(sql1, sql3);
120+
121+
dict.Clear();
122+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"UPDATE ""as_table_log_202201"" SET ""msg"" = 'newmsg'
123+
WHERE (""id"" = '15d2a84f-bd72-4d73-8ad1-466ba8beea60') AND (""createtime"" < '2022-05-01 00:00:00')", dict);
124+
Assert.Equal(3, dict.Count);
125+
sql3 = sql2;
126+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
127+
Assert.Equal(sql1, sql3);
128+
129+
dict.Clear();
130+
sql2 = FreeSql.Internal.Utils.ReplaceSqlConstString(sql1 = @"SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime""
131+
FROM ""as_table_log_202204"" a
132+
WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb
133+
134+
UNION ALL
135+
136+
SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime""
137+
FROM ""as_table_log_202203"" a
138+
WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb
139+
140+
UNION ALL
141+
142+
SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime""
143+
FROM ""as_table_log_202202"" a
144+
WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb
145+
146+
UNION ALL
147+
148+
SELECT * from (SELECT a.""id"", a.""msg"", a.""createtime""
149+
FROM ""as_table_log_202201"" a
150+
WHERE (a.""createtime"" < '2022-05-01 00:00:00')) ftb", dict);
151+
Assert.Equal(1, dict.Count);
152+
sql3 = sql2;
153+
dict.Select(a => sql3 = sql3.Replace(a.Key, "{0}".FormatMySql(a.Value))).ToList();
154+
Assert.Equal(sql1, sql3);
155+
}
49156
}
50157
}

FreeSql/DataAnnotations/TableAttribute.cs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,14 @@ static Regex[] GetRegSqlWhereDateTimes(string columnName, string quoteParameterN
209209
cn = columnName.Replace("[", "\\[").Replace("]", "\\]").Replace(".", "\\.");
210210
return new[]
211211
{
212-
new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase),
213-
new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase),
214-
new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase),
215-
new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase),
216-
new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and\s+)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase),
217-
new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase),
218-
new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase),
219-
new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase),
212+
//new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase),
213+
//new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase),
214+
//new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase),
215+
//new Regex($@"({cn}\s*(<|<=|>|>=|=|between)(\s*))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase),
216+
//new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and\s+)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase),
217+
//new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))to_timestamp\(('[^']+')\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase),
218+
//new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))cast\(('[^']+') as (datetime|timestamp)\)", RegexOptions.IgnoreCase),
219+
//new Regex($@"({cn}\s*(between)\s+'[^']+'\s+and(\s+))('[^']+')::(datetime|timestamp)", RegexOptions.IgnoreCase),
220220

221221
new Regex($@"({cn}\s*(<|<=|>|>=|=)\s*)(datetime|cdate|to_date)\(({quoteParameterName}[\w_]+)\)", RegexOptions.IgnoreCase),
222222
new Regex($@"({cn}\s*(<|<=|>|>=|=)(\s*))to_timestamp\(({quoteParameterName}[\w_]+)\s*,\s*'YYYY-MM-DD[^']+'\)", RegexOptions.IgnoreCase),
@@ -228,13 +228,13 @@ static Regex[] GetRegSqlWhereDateTimes(string columnName, string quoteParameterN
228228
new Regex($@"({cn}\s*(between)\s+{quoteParameterName}[\w_]+\s+and(\s+))({quoteParameterName}[^w_]+)::(datetime|timestamp)", RegexOptions.IgnoreCase),
229229

230230

231-
new Regex($@"{cn}\s*between\s*'([^']+)'\s*and\s*'([^']+)'", RegexOptions.IgnoreCase),
231+
new Regex($@"{cn}\s*between\s*'([^']+)'\s*and\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用
232232
new Regex($@"{cn}\s*between\s*{quoteParameterName}([\w_]+)\s*and\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase),
233233

234-
new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'\s*and\s*{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase),
234+
new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'\s*and\s*{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用
235235
new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)\s*and\s*{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase),
236236

237-
new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase),
237+
new Regex($@"{cn}\s*(<|<=|>|>=)\s*'([^']+)'", RegexOptions.IgnoreCase), //预留暂时不用
238238
new Regex($@"{cn}\s*(<|<=|>|>=)\s*{quoteParameterName}([\w_]+)", RegexOptions.IgnoreCase),
239239
};
240240
});
@@ -256,44 +256,53 @@ static Regex[] GetRegSqlWhereDateTimes(string columnName, string quoteParameterN
256256
public string[] GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils)
257257
{
258258
if (string.IsNullOrWhiteSpace(sqlWhere)) return AllTables;
259+
var dictParams = new Dictionary<string, string>();
260+
var newSqlWhere = Utils.ReplaceSqlConstString(sqlWhere, dictParams);
261+
var tsqlWhere = Utils.ParseSqlWhereLevel1(sqlWhere);
262+
259263
var quoteParameterName = commonUtils.QuoteParamterName("");
260264
var quoteParameterNameCharArray = quoteParameterName.ToCharArray();
261265
var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name);
262266
var regs = GetRegSqlWhereDateTimes($"{(string.IsNullOrWhiteSpace(tb.Alias) ? "" : $"{tb.Alias}.")}{commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name)}", quoteParameterName);
263-
for (var a = 0; a < 16; a++) sqlWhere = regs[a].Replace(sqlWhere, "$1$4");
267+
for (var a = 0; a < 8; a++) newSqlWhere = regs[a].Replace(newSqlWhere, "$1$4");
264268

265-
var m = regs[16].Match(sqlWhere);
266-
if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value);
267-
m = m = regs[18].Match(sqlWhere);
268-
if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value));
269-
m = regs[20].Match(sqlWhere);
270-
if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value));
269+
//var m = regs[8].Match(newSqlWhere);
270+
//if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value);
271+
//m = m = regs[10].Match(newSqlWhere);
272+
//if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value));
273+
//m = regs[12].Match(newSqlWhere);
274+
//if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value));
271275

272-
m = m = regs[17].Match(sqlWhere);
276+
var m = regs[9].Match(newSqlWhere);
273277
if (m.Success)
274278
{
275-
var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault();
276-
var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault();
279+
var val1 = LocalGetParamValue(m.Groups[1].Value);
280+
var val2 = LocalGetParamValue(m.Groups[2].Value);
277281
if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}");
278282
return GetTableNamesByColumnValueRange(val1, val2);
279283
}
280-
m = regs[19].Match(sqlWhere);
284+
m = regs[11].Match(newSqlWhere);
281285
if (m.Success)
282286
{
283-
var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault();
284-
var val2 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[4].Value).FirstOrDefault();
287+
var val1 = LocalGetParamValue(m.Groups[2].Value);
288+
var val2 = LocalGetParamValue(m.Groups[4].Value);
285289
if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}");
286290
return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(val1), ParseColumnValue(val2));
287291
}
288-
m = regs[21].Match(sqlWhere);
292+
m = regs[13].Match(newSqlWhere);
289293
if (m.Success)
290294
{
291-
var val1 = dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault();
295+
var val1 = LocalGetParamValue(m.Groups[2].Value);
292296
if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}");
293297
return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1));
294298
}
295299
return AllTables;
296300

301+
object LocalGetParamValue(string paramName)
302+
{
303+
if (dictParams.TryGetValue(quoteParameterName + paramName, out var trydictVal)) return trydictVal;
304+
return dbParams.Where(a => a.ParameterName.Trim(quoteParameterNameCharArray) == m.Groups[2].Value).FirstOrDefault()?.Value;
305+
}
297306
string[] LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2)
298307
{
299308
switch (opt1)
@@ -317,7 +326,7 @@ string[] LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2)
317326
break;
318327
case ">":
319328
case ">=":
320-
if (opt1 == ">") val1 = val1.AddSeconds(1);
329+
if (opt1 == ">") val1 = val1.AddSeconds(1);
321330
switch (opt2)
322331
{
323332
case "<":

FreeSql/Internal/CommonProvider/InsertProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ public IInsert<T1> AsTable(string tableName)
572572
public IInsert<T1> AsType(Type entityType)
573573
{
574574
if (entityType == typeof(object)) throw new Exception("IInsert.AsType 参数不支持指定为 object");
575+
if (entityType == typeof(T1)) return this;
575576
if (entityType == _table.Type) return this;
576577
var newtb = _commonUtils.GetTableByEntity(entityType);
577578
_table = newtb ?? throw new Exception("IInsert.AsType 参数错误,请传入正确的实体类型");

0 commit comments

Comments
 (0)