diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 485a1d4f..55f11292 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -52,6 +52,29 @@ namespace FreeSql.Tests.MySqlConnectorExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void Format() + { + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs index f3a89e5b..2c513229 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs @@ -162,8 +162,8 @@ namespace FreeSql.Tests.Odbc.DamengExpression public void Random() { var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().Next()).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().NextDouble()).Limit(10).ToList()); } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs index f945fc5e..7f3f3a92 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.dameng.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs index 7e59d641..99ee1aa8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.KingbaseESExpression list.Add(g.kingbaseES.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.kingbaseES.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs index ff5fb312..370a2b01 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,29 @@ namespace FreeSql.Tests.Odbc.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void Format() + { + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs index f645a2da..7df9d90d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs index d4f3d51e..60f1eb3b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as1, ''||((a.""id"" + 1))||'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs index 4954105c..7b6834e1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -51,6 +51,29 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as1, N''+cast((a.[Id] + 1) as varchar)+N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs index 881fc900..036384b5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs @@ -162,8 +162,8 @@ namespace FreeSql.Tests.DamengExpression public void Random() { var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().Next()).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().NextDouble()).Limit(10).ToList()); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs index 7ac61af1..2a9d28a9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.dameng.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs index b89066fa..60b9fd18 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs @@ -50,6 +50,29 @@ namespace FreeSql.Tests.MsAccessExpression list.Add(g.msaccess.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.msaccess.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'+cstr((a.[Id] + 1))+'z-'+(format(a.[CreateTime],'yyyyMM'))+''+(a.[Title])+'' as as1, ''+cstr((a.[Id] + 1))+'x'+cstr((a.[Id] + 1))+'z-'+(format(a.[CreateTime],'yyyyMM'))+''+(a.[Title])+'' as as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index f7610659..0724c12c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,29 @@ namespace FreeSql.Tests.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void Format() + { + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index d46de5c1..bb970771 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index 3facac11..43fac79b 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as1, ''||((a.""id"" + 1))||'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs index c3818765..745192bf 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.ShenTongExpression list.Add(g.shentong.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.shentong.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index ecdadd3b..02d36262 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -65,6 +65,29 @@ namespace FreeSql.Tests.SqlServerExpression list.Add(select.Where(a => a.TitleVarchar == "aaa").ToList()); } + [Fact] + public void Format() + { + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as1, N''+cast((a.[Id] + 1) as varchar)+N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index 0143271c..a64ce3ad 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -50,6 +50,29 @@ namespace FreeSql.Tests.SqliteExpression list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.sqlite.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""Id"" + 1))||'z-'||(strftime('%Y%m',a.""CreateTime""))||''||(a.""Title"")||'' as1, ''||((a.""Id"" + 1))||'x'||((a.""Id"" + 1))||'z-'||(strftime('%Y%m',a.""CreateTime""))||''||(a.""Title"")||'' as2 +FROM ""tb_topic"" a +WHERE (a.""Id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 9cf22a92..8ca5c1c0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -716,31 +716,7 @@ namespace FreeSql.Internal string other3Exp = null; switch (callType.FullName) { - case "System.String": - //$"{id}_{name}" - if (exp3.Method.Name == "Format" && exp3.Object == null && exp3.Arguments[0].NodeType == ExpressionType.Constant) - { - if (exp3.Arguments.Count == 1) return ExpressionLambdaToSql(exp3.Arguments[0], tsc); - var exp3Args0 = (exp3.Arguments[0] as ConstantExpression)?.Value?.ToString().Replace("{{", "{{_freesql_tMp_fLag_"); - var exp3Args1n = exp3.Arguments.Where((a, z) => z > 0).Select(a => ExpressionLambdaToSql(a, tsc)).ToArray(); - var exp3Args0Spt = Regex.Split(exp3Args0, @"{(\d+)}"); - var exp3ArgsConcatType = new Type[exp3Args0Spt.Length]; - exp3Args0Spt[0] = _common.FormatSql("{0}", exp3Args0Spt[0].Replace("{{_freesql_tMp_fLag_", "{{")); - exp3ArgsConcatType[0] = typeof(string); - for (var exp3Args0SptIndex = 1; exp3Args0SptIndex < exp3Args0Spt.Length; exp3Args0SptIndex += 2) - { - var exp3Args1nIndex = int.Parse(exp3Args0Spt[exp3Args0SptIndex]); - exp3Args0Spt[exp3Args0SptIndex] = exp3Args1n[exp3Args1nIndex]; - var expArgsType = exp3.Arguments[exp3Args1nIndex + 1]; - exp3ArgsConcatType[exp3Args0SptIndex] = (expArgsType as UnaryExpression)?.Operand.Type ?? expArgsType.Type; - - exp3Args0Spt[exp3Args0SptIndex + 1] = _common.FormatSql("{0}", exp3Args0Spt[exp3Args0SptIndex + 1].Replace("{{_freesql_tMp_fLag_", "{{")); - exp3ArgsConcatType[exp3Args0SptIndex + 1] = typeof(string); - } - return _common.StringConcat(exp3Args0Spt, exp3ArgsConcatType); - } - other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); - break; + case "System.String": other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); break; case "System.Math": other3Exp = ExpressionLambdaToSqlCallMath(exp3, tsc); break; case "System.DateTime": other3Exp = ExpressionLambdaToSqlCallDateTime(exp3, tsc); break; case "System.TimeSpan": other3Exp = ExpressionLambdaToSqlCallTimeSpan(exp3, tsc); break; diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index 8e36b3de..b9fb0a5f 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -77,7 +77,7 @@ namespace FreeSql.Dameng case "NewGuid": return null; case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as number)"; return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; @@ -222,7 +222,7 @@ namespace FreeSql.Dameng { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Dameng return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 87b1ec06..84686afc 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -220,6 +220,10 @@ namespace FreeSql.MsAccess return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'+{(((a as UnaryExpression)?.Operand.Type ?? a.Type) == typeof(string) ? $"({ExpressionLambdaToSql(a, tsc)})" : $"cstr({ExpressionLambdaToSql(a, tsc)})")}+'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 8fd09ef4..1c409970 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -248,6 +248,11 @@ namespace FreeSql.MySql return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{ExpressionLambdaToSql(a, tsc)},'").ToArray(); + return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } else diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index a04c563d..4220259f 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -77,7 +77,7 @@ namespace FreeSql.Odbc.Dameng case "NewGuid": return null; case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as number)"; return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; @@ -222,7 +222,7 @@ namespace FreeSql.Odbc.Dameng { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Odbc.Dameng return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index d92d1bb3..710fb0b7 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -314,6 +314,10 @@ namespace FreeSql.Odbc.KingbaseES return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index ed583629..cbadc1e1 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -246,6 +246,11 @@ namespace FreeSql.Odbc.MySql return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{ExpressionLambdaToSql(a, tsc)},'").ToArray(); + return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } else diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index ac6dbf3c..b68ff8c4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -222,7 +222,7 @@ namespace FreeSql.Odbc.Oracle { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Odbc.Oracle return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index c3265c27..448007ba 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -336,6 +336,10 @@ namespace FreeSql.Odbc.PostgreSQL return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 1f4bb307..c6ffd0a2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -256,6 +256,20 @@ namespace FreeSql.Odbc.SqlServer return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs0 = ExpressionLambdaToSql(exp.Arguments[0], tsc); + if (exp.Arguments.Count == 1) return expArgs0; + var nchar = expArgs0.StartsWith("N'") ? "N" : ""; + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'+({ExpressionLambdaToSql(a, tsc)})+{nchar}'"; + if (atype == typeof(Guid)) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as char(36))+{nchar}'"; + if (atype.IsNumberType()) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as varchar)+{nchar}'"; + return $"'+cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))+{nchar}'"; + }).ToArray(); + return string.Format(expArgs0, expArgs); } } else diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 7fe04b96..989921f7 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -222,7 +222,7 @@ namespace FreeSql.Oracle { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Oracle return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 0e2c5fe1..3d989330 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -367,6 +367,10 @@ namespace FreeSql.PostgreSQL return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index 35e04a67..8476885f 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -297,6 +297,10 @@ namespace FreeSql.ShenTong return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 78f44002..65bb2fd1 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -255,6 +255,20 @@ namespace FreeSql.SqlServer return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs0 = ExpressionLambdaToSql(exp.Arguments[0], tsc); + if (exp.Arguments.Count == 1) return expArgs0; + var nchar = expArgs0.StartsWith("N'") ? "N" : ""; + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'+({ExpressionLambdaToSql(a, tsc)})+{nchar}'"; + if (atype == typeof(Guid)) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as char(36))+{nchar}'"; + if (atype.IsNumberType()) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as varchar)+{nchar}'"; + return $"'+cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))+{nchar}'"; + }).ToArray(); + return string.Format(expArgs0, expArgs); } } else diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 5a82b092..83888e2b 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -246,6 +246,10 @@ namespace FreeSql.Sqlite return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else