diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs index 2e566ddd..9d3473f7 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.Odbc.OracleExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.oracle.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.Odbc.OracleExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs index 0fe69d3a..020968f2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.OracleExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.oracle.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.OracleExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 9befd68f..5cb20008 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -1,8 +1,6 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index d09da364..2795c374 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Odbc.Oracle { @@ -398,7 +397,57 @@ namespace FreeSql.Odbc.Oracle break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"extract(day from ({left}-({args1})))"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + case "ToString": + if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; + case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; + case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; + case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; + case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; + case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; + case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index a6b53a6b..4ab8f9fd 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -1,5 +1,4 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; using System.Collections.Generic; @@ -485,7 +484,7 @@ namespace FreeSql.Odbc.PostgreSQL case "Equals": return $"({left} = ({args1})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; case "ToString": - left = $"({left})::timestamp"; + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; switch (args1) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 95843601..086a6daf 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -374,7 +374,7 @@ namespace FreeSql.Odbc.SqlServer case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": - left = $"cast({left} as datetime)"; + if (left.EndsWith(" as datetime)") == false) left = $"cast({left} as datetime)"; if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)"; switch (args1.TrimStart('N')) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 5169f563..2029c68e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Oracle { @@ -398,7 +397,57 @@ namespace FreeSql.Oracle break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"extract(day from ({left}-({args1})))"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + case "ToString": + if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; + case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; + case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; + case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; + case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; + case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; + case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 157606eb..6c56f6a2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -1,5 +1,4 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; using System; using System.Collections; @@ -516,7 +515,7 @@ namespace FreeSql.PostgreSQL case "Equals": return $"({left} = ({args1})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; case "ToString": - left = $"({left})::timestamp"; + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; switch (args1) { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 573b13fd..a657b039 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -374,7 +374,7 @@ namespace FreeSql.SqlServer case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": - left = $"cast({left} as datetime)"; + if (left.EndsWith(" as datetime)") == false) left = $"cast({left} as datetime)"; if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)"; switch (args1.TrimStart('N')) { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 5c1ab0fa..2fb321ea 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -1,8 +1,6 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text;