Skip to content

Commit 2a42731

Browse files
2881028810
authored andcommitted
- 增加 Oracle 表达式解析 yyyyMMdd 常用 c# 日期格式化;
1 parent 70266c0 commit 2a42731

File tree

10 files changed

+200
-56
lines changed

10 files changed

+200
-56
lines changed

FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,52 @@ class TestTypeParentInfo
4141
public List<TestTypeInfo> Types { get; set; }
4242
public DateTime Time2 { get; set; }
4343
}
44+
45+
[Fact]
46+
public void this_ToString()
47+
{
48+
var data = new List<object>();
49+
data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList());
50+
data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList());
51+
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList());
52+
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
53+
//FROM `tb_topic111333` a
54+
//WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now()));
55+
56+
//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
57+
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
58+
//WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()));
59+
60+
//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
61+
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
62+
//WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()))
63+
64+
g.oracle.Insert(new Topic()).ExecuteAffrows();
65+
var dtn = DateTime.Parse("2020-1-1 0:0:0");
66+
var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a))
67+
.Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a)))
68+
.Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a)))
69+
.Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a)))
70+
.Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a)));
71+
foreach (var dt in dts)
72+
{
73+
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString()));
74+
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss")));
75+
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm")));
76+
Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH")));
77+
Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd")));
78+
Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM")));
79+
Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss")));
80+
Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm")));
81+
Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH")));
82+
Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd")));
83+
Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM")));
84+
Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy")));
85+
Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss")));
86+
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")));
87+
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")));
88+
}
89+
}
4490
[Fact]
4591
public void Now()
4692
{
@@ -587,26 +633,6 @@ public void this_Equals()
587633
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
588634
//WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now()))
589635
}
590-
[Fact]
591-
public void this_ToString()
592-
{
593-
var data = new List<object>();
594-
data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList());
595-
data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList());
596-
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList());
597-
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
598-
//FROM `tb_topic111333` a
599-
//WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now()));
600-
601-
//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
602-
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
603-
//WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()));
604-
605-
//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
606-
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
607-
//WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()))
608-
}
609-
610636
[Fact]
611637
public void DateTime_Compare()
612638
{

FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,52 @@ class TestTypeParentInfo
4141
public List<TestTypeInfo> Types { get; set; }
4242
public DateTime Time2 { get; set; }
4343
}
44+
45+
[Fact]
46+
public void this_ToString()
47+
{
48+
var data = new List<object>();
49+
data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList());
50+
data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList());
51+
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList());
52+
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
53+
//FROM `tb_topic111333` a
54+
//WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now()));
55+
56+
//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
57+
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
58+
//WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()));
59+
60+
//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
61+
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
62+
//WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()))
63+
64+
g.oracle.Insert(new Topic()).ExecuteAffrows();
65+
var dtn = DateTime.Parse("2020-1-1 0:0:0");
66+
var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a))
67+
.Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a)))
68+
.Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a)))
69+
.Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a)))
70+
.Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a)));
71+
foreach (var dt in dts)
72+
{
73+
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString()));
74+
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss")));
75+
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm")));
76+
Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH")));
77+
Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd")));
78+
Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM")));
79+
Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss")));
80+
Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm")));
81+
Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH")));
82+
Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd")));
83+
Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM")));
84+
Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy")));
85+
Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss")));
86+
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")));
87+
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")));
88+
}
89+
}
4490
[Fact]
4591
public void Now()
4692
{
@@ -587,26 +633,6 @@ public void this_Equals()
587633
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
588634
//WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now()))
589635
}
590-
[Fact]
591-
public void this_ToString()
592-
{
593-
var data = new List<object>();
594-
data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList());
595-
data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList());
596-
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList());
597-
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
598-
//FROM `tb_topic111333` a
599-
//WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now()));
600-
601-
//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
602-
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
603-
//WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()));
604-
605-
//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
606-
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
607-
//WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()))
608-
}
609-
610636
[Fact]
611637
public void DateTime_Compare()
612638
{

Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using FreeSql.Internal;
2-
using FreeSql.Internal.Model;
32
using System;
43
using System.Collections;
5-
using System.Collections.Generic;
64
using System.Linq;
75
using System.Linq.Expressions;
86
using System.Text;

Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
using FreeSql.Internal;
2-
using FreeSql.Internal.Model;
32
using System;
43
using System.Collections;
5-
using System.Collections.Generic;
64
using System.Linq;
75
using System.Linq.Expressions;
86
using System.Text;
7+
using System.Text.RegularExpressions;
98

109
namespace FreeSql.Odbc.Oracle
1110
{
@@ -398,7 +397,57 @@ public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression ex
398397
break;
399398
case "Equals": return $"({left} = {args1})";
400399
case "CompareTo": return $"extract(day from ({left}-({args1})))";
401-
case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null;
400+
case "ToString":
401+
if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')";
402+
if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')";
403+
switch (args1)
404+
{
405+
case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')";
406+
case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')";
407+
case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')";
408+
case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')";
409+
case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')";
410+
case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')";
411+
case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')";
412+
case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')";
413+
case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')";
414+
case "'yyyyMM'": return $"to_char({left},'YYYYMM')";
415+
case "'yyyy'": return $"to_char({left},'YYYY')";
416+
case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')";
417+
}
418+
args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m =>
419+
{
420+
switch (m.Groups[1].Value)
421+
{
422+
case "yyyy": return $"YYYY";
423+
case "yy": return $"YY";
424+
case "MM": return $"%_a1";
425+
case "dd": return $"%_a2";
426+
case "HH": return $"%_a3";
427+
case "hh": return $"%_a4";
428+
case "mm": return $"%_a5";
429+
case "ss": return $"SS";
430+
case "tt": return $"%_a6";
431+
}
432+
return m.Groups[0].Value;
433+
});
434+
var isMatched = false;
435+
args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m =>
436+
{
437+
isMatched = true;
438+
switch (m.Groups[1].Value)
439+
{
440+
case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'";
441+
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},'";
442+
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},'";
443+
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},'";
444+
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},'";
445+
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},'";
446+
case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'";
447+
}
448+
return m.Groups[0].Value;
449+
}).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM");
450+
return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''");
402451
}
403452
}
404453
return null;

Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using FreeSql.Internal;
2-
using FreeSql.Internal.Model;
32
using System;
43
using System.Collections;
54
using System.Collections.Generic;
@@ -485,7 +484,7 @@ public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression ex
485484
case "Equals": return $"({left} = ({args1})::timestamp)";
486485
case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)";
487486
case "ToString":
488-
left = $"({left})::timestamp";
487+
if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp";
489488
if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')";
490489
switch (args1)
491490
{

Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression ex
374374
case "Equals": return $"({left} = {args1})";
375375
case "CompareTo": return $"datediff(second,{args1},{left})";
376376
case "ToString":
377-
left = $"cast({left} as datetime)";
377+
if (left.EndsWith(" as datetime)") == false) left = $"cast({left} as datetime)";
378378
if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)";
379379
switch (args1.TrimStart('N'))
380380
{

0 commit comments

Comments
 (0)