diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5a301088..3ae9d226 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 8eb3c10a..a370eb18 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 2fae56b7..1d835e33 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index f91ba287..f6f9ea97 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2869de25..7afe75eb 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.6.100 + 3.0.100 FreeSql DbFirst 实体生成器 diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs index a52036a6..a9e87243 100644 --- a/Extensions/FreeSql.Generator/RazorContentManager.cs +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -63,9 +63,9 @@ namespace @gen.NameSpace { @foreach (var col in gen.columns) { - if (string.IsNullOrEmpty(col.Coment) == false) { + if (string.IsNullOrEmpty(col.Comment) == false) { @:/// - @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") + @:/// @col.Comment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") @:/// } @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col, true)) + ""]"") @@ -154,9 +154,9 @@ namespace @gen.NameSpace { var findfks = fks.Where(fkaa => fkaa.Columns.Where(fkaac1 => fkaac1.Name == col.Name).Any()); var csname = gen.GetCsName(col.Name); - if (string.IsNullOrEmpty(col.Coment) == false) { + if (string.IsNullOrEmpty(col.Comment) == false) { @:/// - @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") + @:/// @col.Comment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") @:/// } @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col, true)) + ""]"") diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 0e0b1e37..a759dcd7 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 88ff6b5c..b259ed9c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 8551c248..1faae1a2 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -40,7 +40,7 @@ namespace FreeSql { _dbsetPriv?.Dispose(); _dbPriv?.Dispose(); - this.DataFilter.Dispose(); + this.DataFilter?.Dispose(); } finally { diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 39ebd39a..1a922fa8 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.6.100 + 3.0.100 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/.editorconfig b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/.editorconfig new file mode 100644 index 00000000..d2f6a096 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# xUnit2000: Constants and literals should be the expected argument +dotnet_diagnostic.xUnit2000.severity = none diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/FreeSql.Tests.Provider.GBase.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/FreeSql.Tests.Provider.GBase.csproj new file mode 100644 index 00000000..6abc2f4f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/FreeSql.Tests.Provider.GBase.csproj @@ -0,0 +1,38 @@ + + + + net5.0 + false + + + + FreeSql.Tests.Provider.GBase.xml + 3 + 1701;1702;1591 + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + d:\testcode\GeneralData.EntityFrameworkCore.GBase.DataProvider.dll + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/FreeSql.Tests.Provider.GBase.xml b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/FreeSql.Tests.Provider.GBase.xml new file mode 100644 index 00000000..dbda2f56 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/FreeSql.Tests.Provider.GBase.xml @@ -0,0 +1,13 @@ + + + + FreeSql.Tests.Provider.GBase + + + + + 编号 + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseDeleteTest.cs new file mode 100644 index 00000000..5fa2bf09 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseDeleteTest.cs @@ -0,0 +1,128 @@ +using FreeSql.DataAnnotations; +using IBM.Data.Informix; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseDeleteTest + { + + IDelete delete => g.gbase.Delete(); + + [Table(Name = "tb_topic_del")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.gbase.Delete().ToSql()); + var sql = g.gbase.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM tb_topic_del WHERE (Id IN (1,2))", sql); + + sql = g.gbase.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM tb_topic_del WHERE (Id = 1)", sql); + + sql = g.gbase.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM tb_topic_del WHERE (Id IN (1,2))", sql); + + sql = g.gbase.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM tb_topic_del WHERE (Id = 1)", sql); + + sql = g.gbase.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM MultiPkTopic WHERE (Id1 = 1 AND Id2 = 10 OR Id1 = 2 AND Id2 = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM tb_topic_del WHERE (Id = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM tb_topic_del WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM tb_topic_del WHERE (Id = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM tb_topic_del WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.gbase.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + Assert.Throws(() => delete.Where(a => a.Id > 0).ExecuteDeleted()); + } + + [Fact] + public void AsTable() + { + //var connectionBuilder = new IfxConnectionStringBuilder + //{ + // Host = "192.168.164.134", + // Service = "9088", + // Server = "gbase01", + // Database = "testdb", + // UID = "gbasedbt", + // Pwd = "GBase123", + // DbLocale = "zh_CN.utf8", + // ClientLocale = "zh_CN.utf8", + // PersistSecurityInfo = true + //}; + //using (IfxConnection conn = new IfxConnection(connectionBuilder.ConnectionString)) + //{ + // conn.Open(); + + // var cmd = conn.CreateCommand(); + // cmd.CommandText = "select 1 from dual"; + // var val = cmd.ExecuteScalar(); + + // conn.Close(); + //} + + + Assert.Null(g.gbase.Delete().ToSql()); + var sql = g.gbase.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM TopicAsTable WHERE (Id IN (1,2))", sql); + + sql = g.gbase.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM TopicAsTable WHERE (Id = 1)", sql); + + sql = g.gbase.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM TopicAsTable WHERE (Id IN (1,2))", sql); + + sql = g.gbase.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM TopicAsTable WHERE (Id = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..dae18691 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,437 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.gbase; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb01 t1 +USING (SELECT 1 as id FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb01 t1 +USING (SELECT 1 as id FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb01 t1 +USING (SELECT 2 as id FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb01 t1 +USING (SELECT 1 as id FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb01 t1 +USING (SELECT 1 as id FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb02 t1 +USING (SELECT 1 as id, '01' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb02 t1 +USING (SELECT 1 as id, '011' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb02 t1 +USING (SELECT 2 as id, '02' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb02 t1 +USING (SELECT 1 as id, '01' as name FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb02 t1 +USING (SELECT 1 as id, '001' as name FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb022 t1 +USING (SELECT 1 as id, '01' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb022 t1 +USING (SELECT 1 as id, '011' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb022 t1 +USING (SELECT 2 as id, '02' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb022 t1 +USING (SELECT 1 as id, '01' as name FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb022 t1 +USING (SELECT 1 as id, '001' as name FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbioudb022(name) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbioudb022(name) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbioudb022(name) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbioudb022(name) +SELECT * FROM ( + SELECT '01' FROM dual +UNION ALL + SELECT '02' FROM dual +UNION ALL + SELECT '03' FROM dual +UNION ALL + SELECT '04' FROM dual +) ftbtmp", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbioudb022(name) +SELECT * FROM ( + SELECT '001' FROM dual +UNION ALL + SELECT '002' FROM dual +UNION ALL + SELECT '003' FROM dual +UNION ALL + SELECT '004' FROM dual +) ftbtmp", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb022 t1 +USING (SELECT 1 as id, '100001' as name FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name) + +; + +INSERT INTO tbioudb022(name) +SELECT * FROM ( + SELECT '00001' FROM dual +UNION ALL + SELECT '00002' FROM dual +UNION ALL + SELECT '00003' FROM dual +UNION ALL + SELECT '00004' FROM dual +) ftbtmp", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb03 t1 +USING (SELECT 1 as id1, '01' as id2, '01' as name FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb03 t1 +USING (SELECT 1 as id1, '01' as id2, '011' as name FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb03 t1 +USING (SELECT 2 as id1, '02' as id2, '02' as name FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb03 t1 +USING (SELECT 1 as id1, '01' as id2, '01' as name FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb03 t1 +USING (SELECT 1 as id1, '01' as id2, '001' as name FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb04 t1 +USING (SELECT 1 as id, '01' as name, 0 as version, current as CreateTime FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb04 t1 +USING (SELECT 1 as id, '011' as name, 0 as version, current as CreateTime FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb04 t1 +USING (SELECT 2 as id, '02' as name, 0 as version, current as CreateTime FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb04 t1 +USING (SELECT 1 as id, '01' as name, 0 as version, current as CreateTime FROM dual +UNION ALL + SELECT 2, '02', 0, current FROM dual +UNION ALL + SELECT 3, '03', 0, current FROM dual +UNION ALL + SELECT 4, '04', 0, current FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbioudb04 t1 +USING (SELECT 1 as id, '001' as name, 0 as version, current as CreateTime FROM dual +UNION ALL + SELECT 2, '002', 0, current FROM dual +UNION ALL + SELECT 3, '003', 0, current FROM dual +UNION ALL + SELECT 4, '004', 0, current FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertOrUpdateTest.cs new file mode 100644 index 00000000..0adafe61 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertOrUpdateTest.cs @@ -0,0 +1,479 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseInsertOrUpdateTest + { + IFreeSql fsql => g.gbase; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou01 t1 +USING (SELECT 1 as id FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou01 t1 +USING (SELECT 1 as id FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou01 t1 +USING (SELECT 2 as id FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou01 t1 +USING (SELECT 1 as id FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou01 t1 +USING (SELECT 1 as id FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.id = t2.id) +WHEN NOT MATCHED THEN + insert (id) + values (t2.id)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou02 t1 +USING (SELECT 1 as id, '01' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou02 t1 +USING (SELECT 1 as id, '011' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou02 t1 +USING (SELECT 2 as id, '02' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou02 t1 +USING (SELECT 1 as id, '01' as name FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou02 t1 +USING (SELECT 1 as id, '001' as name FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou022 t1 +USING (SELECT 1 as id, '01' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou022 t1 +USING (SELECT 1 as id, '011' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou022 t1 +USING (SELECT 2 as id, '02' as name FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou022 t1 +USING (SELECT 1 as id, '01' as name FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou022 t1 +USING (SELECT 1 as id, '001' as name FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbiou022(name) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbiou022(name) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbiou022(name) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbiou022(name) +SELECT * FROM ( + SELECT '01' FROM dual +UNION ALL + SELECT '02' FROM dual +UNION ALL + SELECT '03' FROM dual +UNION ALL + SELECT '04' FROM dual +) ftbtmp", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO tbiou022(name) +SELECT * FROM ( + SELECT '001' FROM dual +UNION ALL + SELECT '002' FROM dual +UNION ALL + SELECT '003' FROM dual +UNION ALL + SELECT '004' FROM dual +) ftbtmp", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou022 t1 +USING (SELECT 1 as id, '100001' as name FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id, name) + values (t2.id, t2.name) + +; + +INSERT INTO tbiou022(name) +SELECT * FROM ( + SELECT '00001' FROM dual +UNION ALL + SELECT '00002' FROM dual +UNION ALL + SELECT '00003' FROM dual +UNION ALL + SELECT '00004' FROM dual +) ftbtmp", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou03 t1 +USING (SELECT 1 as id1, '01' as id2, '01' as name FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou03 t1 +USING (SELECT 1 as id1, '01' as id2, '011' as name FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou03 t1 +USING (SELECT 2 as id1, '02' as id2, '02' as name FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou03 t1 +USING (SELECT 1 as id1, '01' as id2, '01' as name FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou03 t1 +USING (SELECT 1 as id1, '01' as id2, '001' as name FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.id1 = t2.id1 AND t1.id2 = t2.id2) +WHEN MATCHED THEN + update set t1.name = t2.name +WHEN NOT MATCHED THEN + insert (id1, id2, name) + values (t2.id1, t2.id2, t2.name)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou04 t1 +USING (SELECT 1 as id, '01' as name, 0 as version, current as CreateTime FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name, t1.version = t1.version + 1 +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou04 t1 +USING (SELECT 1 as id, '011' as name, 0 as version, current as CreateTime FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name, t1.version = t1.version + 1 +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou04 t1 +USING (SELECT 2 as id, '02' as name, 0 as version, current as CreateTime FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name, t1.version = t1.version + 1 +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou04 t1 +USING (SELECT 1 as id, '01' as name, 0 as version, current as CreateTime FROM dual +UNION ALL + SELECT 2, '02', 0, current FROM dual +UNION ALL + SELECT 3, '03', 0, current FROM dual +UNION ALL + SELECT 4, '04', 0, current FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name, t1.version = t1.version + 1 +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO tbiou04 t1 +USING (SELECT 1 as id, '001' as name, 0 as version, current as CreateTime FROM dual +UNION ALL + SELECT 2, '002', 0, current FROM dual +UNION ALL + SELECT 3, '003', 0, current FROM dual +UNION ALL + SELECT 4, '004', 0, current FROM dual ) t2 ON (t1.id = t2.id) +WHEN MATCHED THEN + update set t1.name = t2.name, t1.version = t1.version + 1 +WHEN NOT MATCHED THEN + insert (id, name, version, CreateTime) + values (t2.id, t2.name, t2.version, t2.CreateTime)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertTest.cs new file mode 100644 index 00000000..f84021d8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseInsertTest.cs @@ -0,0 +1,439 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseInsertTest + { + + IInsert insert => g.gbase.Insert(); + + [Table(Name = "TB_TOPIC_INSERT")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO TB_TOPIC_INSERT(Clicks, Title, CreateTime) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal(@"INSERT INTO TB_TOPIC_INSERT(Clicks, Title, CreateTime) +SELECT * FROM ( + SELECT 0, 'newtitle0', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 100, 'newtitle1', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 200, 'newtitle2', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 300, 'newtitle3', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 400, 'newtitle4', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 500, 'newtitle5', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 600, 'newtitle6', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 700, 'newtitle7', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 800, 'newtitle8', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 900, 'newtitle9', '0001-01-01 00:00:00.000' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT INTO TB_TOPIC_INSERT(Title) +SELECT * FROM ( + SELECT 'newtitle0' FROM dual +UNION ALL + SELECT 'newtitle1' FROM dual +UNION ALL + SELECT 'newtitle2' FROM dual +UNION ALL + SELECT 'newtitle3' FROM dual +UNION ALL + SELECT 'newtitle4' FROM dual +UNION ALL + SELECT 'newtitle5' FROM dual +UNION ALL + SELECT 'newtitle6' FROM dual +UNION ALL + SELECT 'newtitle7' FROM dual +UNION ALL + SELECT 'newtitle8' FROM dual +UNION ALL + SELECT 'newtitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT INTO TB_TOPIC_INSERT(Clicks, Title) +SELECT * FROM ( + SELECT 0, 'newtitle0' FROM dual +UNION ALL + SELECT 100, 'newtitle1' FROM dual +UNION ALL + SELECT 200, 'newtitle2' FROM dual +UNION ALL + SELECT 300, 'newtitle3' FROM dual +UNION ALL + SELECT 400, 'newtitle4' FROM dual +UNION ALL + SELECT 500, 'newtitle5' FROM dual +UNION ALL + SELECT 600, 'newtitle6' FROM dual +UNION ALL + SELECT 700, 'newtitle7' FROM dual +UNION ALL + SELECT 800, 'newtitle8' FROM dual +UNION ALL + SELECT 900, 'newtitle9' FROM dual +) ftbtmp", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT INTO TB_TOPIC_INSERT(Title) +SELECT * FROM ( + SELECT 'newtitle0' FROM dual +UNION ALL + SELECT 'newtitle1' FROM dual +UNION ALL + SELECT 'newtitle2' FROM dual +UNION ALL + SELECT 'newtitle3' FROM dual +UNION ALL + SELECT 'newtitle4' FROM dual +UNION ALL + SELECT 'newtitle5' FROM dual +UNION ALL + SELECT 'newtitle6' FROM dual +UNION ALL + SELECT 'newtitle7' FROM dual +UNION ALL + SELECT 'newtitle8' FROM dual +UNION ALL + SELECT 'newtitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal(@"INSERT INTO TB_TOPIC_INSERT(Clicks, Title) +SELECT * FROM ( + SELECT 0, 'newtitle0' FROM dual +UNION ALL + SELECT 100, 'newtitle1' FROM dual +UNION ALL + SELECT 200, 'newtitle2' FROM dual +UNION ALL + SELECT 300, 'newtitle3' FROM dual +UNION ALL + SELECT 400, 'newtitle4' FROM dual +UNION ALL + SELECT 500, 'newtitle5' FROM dual +UNION ALL + SELECT 600, 'newtitle6' FROM dual +UNION ALL + SELECT 700, 'newtitle7' FROM dual +UNION ALL + SELECT 800, 'newtitle8' FROM dual +UNION ALL + SELECT 900, 'newtitle9' FROM dual +) ftbtmp", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT INTO TB_TOPIC_INSERT(Clicks, Title) +SELECT * FROM ( + SELECT 0, 'newtitle0' FROM dual +UNION ALL + SELECT 100, 'newtitle1' FROM dual +UNION ALL + SELECT 200, 'newtitle2' FROM dual +UNION ALL + SELECT 300, 'newtitle3' FROM dual +UNION ALL + SELECT 400, 'newtitle4' FROM dual +UNION ALL + SELECT 500, 'newtitle5' FROM dual +UNION ALL + SELECT 600, 'newtitle6' FROM dual +UNION ALL + SELECT 700, 'newtitle7' FROM dual +UNION ALL + SELECT 800, 'newtitle8' FROM dual +UNION ALL + SELECT 900, 'newtitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal(@"INSERT INTO TB_TOPIC_INSERT(Clicks) +SELECT * FROM ( + SELECT 0 FROM dual +UNION ALL + SELECT 100 FROM dual +UNION ALL + SELECT 200 FROM dual +UNION ALL + SELECT 300 FROM dual +UNION ALL + SELECT 400 FROM dual +UNION ALL + SELECT 500 FROM dual +UNION ALL + SELECT 600 FROM dual +UNION ALL + SELECT 700 FROM dual +UNION ALL + SELECT 800 FROM dual +UNION ALL + SELECT 900 FROM dual +) ftbtmp", sql); + + g.gbase.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.gbase.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.gbase.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "TB_TOPICIGNORECOLUMNS")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.NoneParameter().AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.gbase.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Throws(() => insert.AppendData(items.First()).ExecuteInserted()); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO Topic_InsertAsTable(Clicks, Title, CreateTime) VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO Topic_InsertAsTable(Clicks, Title, CreateTime) +SELECT * FROM ( + SELECT 0, 'newTitle0', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 100, 'newTitle1', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 200, 'newTitle2', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 300, 'newTitle3', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 400, 'newTitle4', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 500, 'newTitle5', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 600, 'newTitle6', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 700, 'newTitle7', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 800, 'newTitle8', '0001-01-01 00:00:00.000' FROM dual +UNION ALL + SELECT 900, 'newTitle9', '0001-01-01 00:00:00.000' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO Topic_InsertAsTable(Title) +SELECT * FROM ( + SELECT 'newTitle0' FROM dual +UNION ALL + SELECT 'newTitle1' FROM dual +UNION ALL + SELECT 'newTitle2' FROM dual +UNION ALL + SELECT 'newTitle3' FROM dual +UNION ALL + SELECT 'newTitle4' FROM dual +UNION ALL + SELECT 'newTitle5' FROM dual +UNION ALL + SELECT 'newTitle6' FROM dual +UNION ALL + SELECT 'newTitle7' FROM dual +UNION ALL + SELECT 'newTitle8' FROM dual +UNION ALL + SELECT 'newTitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO Topic_InsertAsTable(Clicks, Title) +SELECT * FROM ( + SELECT 0, 'newTitle0' FROM dual +UNION ALL + SELECT 100, 'newTitle1' FROM dual +UNION ALL + SELECT 200, 'newTitle2' FROM dual +UNION ALL + SELECT 300, 'newTitle3' FROM dual +UNION ALL + SELECT 400, 'newTitle4' FROM dual +UNION ALL + SELECT 500, 'newTitle5' FROM dual +UNION ALL + SELECT 600, 'newTitle6' FROM dual +UNION ALL + SELECT 700, 'newTitle7' FROM dual +UNION ALL + SELECT 800, 'newTitle8' FROM dual +UNION ALL + SELECT 900, 'newTitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO Topic_InsertAsTable(Title) +SELECT * FROM ( + SELECT 'newTitle0' FROM dual +UNION ALL + SELECT 'newTitle1' FROM dual +UNION ALL + SELECT 'newTitle2' FROM dual +UNION ALL + SELECT 'newTitle3' FROM dual +UNION ALL + SELECT 'newTitle4' FROM dual +UNION ALL + SELECT 'newTitle5' FROM dual +UNION ALL + SELECT 'newTitle6' FROM dual +UNION ALL + SELECT 'newTitle7' FROM dual +UNION ALL + SELECT 'newTitle8' FROM dual +UNION ALL + SELECT 'newTitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO Topic_InsertAsTable(Clicks, Title) +SELECT * FROM ( + SELECT 0, 'newTitle0' FROM dual +UNION ALL + SELECT 100, 'newTitle1' FROM dual +UNION ALL + SELECT 200, 'newTitle2' FROM dual +UNION ALL + SELECT 300, 'newTitle3' FROM dual +UNION ALL + SELECT 400, 'newTitle4' FROM dual +UNION ALL + SELECT 500, 'newTitle5' FROM dual +UNION ALL + SELECT 600, 'newTitle6' FROM dual +UNION ALL + SELECT 700, 'newTitle7' FROM dual +UNION ALL + SELECT 800, 'newTitle8' FROM dual +UNION ALL + SELECT 900, 'newTitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO Topic_InsertAsTable(Clicks, Title) +SELECT * FROM ( + SELECT 0, 'newTitle0' FROM dual +UNION ALL + SELECT 100, 'newTitle1' FROM dual +UNION ALL + SELECT 200, 'newTitle2' FROM dual +UNION ALL + SELECT 300, 'newTitle3' FROM dual +UNION ALL + SELECT 400, 'newTitle4' FROM dual +UNION ALL + SELECT 500, 'newTitle5' FROM dual +UNION ALL + SELECT 600, 'newTitle6' FROM dual +UNION ALL + SELECT 700, 'newTitle7' FROM dual +UNION ALL + SELECT 800, 'newTitle8' FROM dual +UNION ALL + SELECT 900, 'newTitle9' FROM dual +) ftbtmp", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO Topic_InsertAsTable(Clicks) +SELECT * FROM ( + SELECT 0 FROM dual +UNION ALL + SELECT 100 FROM dual +UNION ALL + SELECT 200 FROM dual +UNION ALL + SELECT 300 FROM dual +UNION ALL + SELECT 400 FROM dual +UNION ALL + SELECT 500 FROM dual +UNION ALL + SELECT 600 FROM dual +UNION ALL + SELECT 700 FROM dual +UNION ALL + SELECT 800 FROM dual +UNION ALL + SELECT 900 FROM dual +) ftbtmp", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseSelectTest.cs new file mode 100644 index 00000000..5fa9883a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseSelectTest.cs @@ -0,0 +1,1850 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseSelectTest + { + + ISelect select => g.gbase.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.gbase.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + Assert.Equal(@"SELECT a.Id, a.Parent_id, a__Parent.Id as3, a__Parent.Parent_id as4, a__Parent.Ddd, a__Parent.Name, a.Ddd as7, a.Name as8 +FROM Tag a +LEFT JOIN Tag a__Parent ON a__Parent.Id = a.Parent_id +LEFT JOIN Tag a__Parent__Parent ON a__Parent__Parent.Id = a__Parent.Parent_id +WHERE (a__Parent__Parent.Name = '粤语')", t0); + + //OneToMany + var t1 = g.gbase.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + Assert.Equal(@"SELECT a.Id, a.Parent_id, a.Ddd, a.Name +FROM Tag a +WHERE (exists(SELECT FIRST 1 1 + FROM Tag t + LEFT JOIN Tag t__Parent ON t__Parent.Id = t.Parent_id + WHERE (t__Parent.Id = 10) AND (t.Parent_id = a.Id)))", t1); + + //ManyToMany + var t2 = g.gbase.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + Assert.Equal(@"SELECT a.Id, a.Create_time, a.Is_deleted, a.Title, a.Url +FROM Song a +WHERE (exists(SELECT FIRST 1 1 + FROM Song_tag Mt_Ms + WHERE (Mt_Ms.Song_id = a.Id) AND (exists(SELECT FIRST 1 1 + FROM Tag t + WHERE (t.Name = '国语') AND (t.Id = Mt_Ms.Tag_id)))))", t2); + } + + [Fact] + public void Lazy() + { + var tags = g.gbase.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.gbase.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.firebird.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.gbase.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.firebird.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + g.gbase.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.gbase.Select().ToList(); + var testGuidId6 = g.gbase.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.gbase.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.gbase.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.gbase.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + g.gbase.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.gbase.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo b ON a.TypeGuid = b.Guid", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo b ON a.TypeGuid = b.Guid LEFT JOIN TestTypeParentInfo c ON b.ParentId = c.Id", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo b ON b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo b ON b.Guid = a.TypeGuid AND b.Name = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid LEFT JOIN TestTypeParentInfo c ON c.Id = a__Type.ParentId", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo b ON a.TypeGuid = b.Guid LEFT JOIN TestTypeParentInfo c ON b.ParentId = c.Id", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo b ON b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo b ON b.Guid = a.TypeGuid AND b.Name = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid INNER JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid INNER JOIN TestTypeParentInfo c ON c.Id = a__Type.ParentId", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo b ON a.TypeGuid = b.Guid INNER JOIN TestTypeParentInfo c ON b.ParentId = c.Id", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo b ON b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo b ON b.Guid = a.TypeGuid AND b.Name = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid RIGHT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid RIGHT JOIN TestTypeParentInfo c ON c.Id = a__Type.ParentId", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo b ON a.TypeGuid = b.Guid RIGHT JOIN TestTypeParentInfo c ON b.ParentId = c.Id", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE (a.Id = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE ((a.Id = 10 AND a.Id > 10 OR a.Clicks > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE (a.Id = 10) AND (a.Clicks > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid WHERE (a__Type.Name = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid WHERE (a__Type.Name = 'typeTitle' AND a__Type.Guid = a.TypeGuid)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Name = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a, TestTypeInfo b WHERE (b.Guid = a.TypeGuid AND b.Name = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a, TestTypeInfo b WHERE (b.Name = 'typeTitle' AND b.Guid = a.TypeGuid)", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a, TestTypeParentInfo c WHERE (c.Name = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a, TestTypeInfo b, TestTypeParentInfo c WHERE (a.Id = 10 AND c.Name = 'xxx') AND (b.ParentId = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.Clicks > 100 and a.Id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE (a.Clicks > 100 and a.Id = ?)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE (a.Id = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE ((a.Id = 10 AND a.Id > 10 OR a.Clicks > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE (a.Id = 10) AND (a.Clicks > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid WHERE (a__Type.Name = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid WHERE (a__Type.Name = 'typeTitle' AND a__Type.Guid = a.TypeGuid)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22 a LEFT JOIN TestTypeInfo a__Type ON a__Type.Guid = a.TypeGuid LEFT JOIN TestTypeParentInfo a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Name = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a, TestTypeInfo b, TestTypeParentInfo c WHERE (a.Id = 10 AND c.Name = 'xxx') AND (b.ParentId = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.Clicks > 100 and a.Id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a WHERE (a.Clicks > 100 and a.Id = ?)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a, TestTypeInfo b, TestTypeParentInfo c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.Clicks > 100 and a.Id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + + [Table(Name = "TestInfoT1")] + class TestInfo + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void GroupBy() + { + //var groupby = select.From((s, b, c) => s + // .Where(a => a.Id == 1) + //) + //.GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + //.Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + //.Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + //.OrderBy(a => a.Key.tt2) + //.OrderByDescending(a => a.Count()) + //.Offset(10) + //.Limit(2) + //.Count(out var trycount) + //.ToList(a => new + //{ + // a.Key.tt2, + // cou1 = a.Count(), + // cou2 = a.Count(a.Value.Item3.Id), + // arg1 = a.Avg(a.Key.mod4), + // ccc2 = a.Key.tt2 ?? "now()", + // //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + // ccc3 = a.Max(a.Value.Item3.Id) + //}); + + var testpid1 = g.gbase.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.gbase.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + //var aggsql2 = select + // .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + // .ToSql(b => new + // { + // b.Key.Title, + // b.Key.yyyy, + + // cou = b.Count(), + // sum2 = b.Sum(b.Value.TypeGuid) + // }); + //var aggtolist2 = select + // .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + // .ToList(b => new + // { + // b.Key.Title, + // b.Key.yyyy, + + // cou = b.Count(), + // sum2 = b.Sum(b.Value.TypeGuid) + // }); + //var aggtolist22 = select + // .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + // .ToDictionary(b => new + // { + // b.Key.Title, + // b.Key.yyyy, + + // cou = b.Count(), + // sum2 = b.Sum(b.Value.TypeGuid) + // }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + //var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + //var sql3 = select.Page(3, 10).ToList(); + + //var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + //var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + //var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.Id as1, a.Clicks as2, a.TypeGuid as3, a.Title as4, a.CreateTime as5, (SELECT sum(b.Id) + FROM tb_topic22 b) as6 +FROM tb_topic22 a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + Assert.Equal(@"SELECT a.Id as1, a.Clicks as2, a.TypeGuid as3, a.Title as4, a.CreateTime as5, (SELECT min(b.Id) + FROM tb_topic22 b) as6 +FROM tb_topic22 a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.Id as1, a.Clicks as2, a.TypeGuid as3, a.Title as4, a.CreateTime as5, (SELECT max(b.Id) + FROM tb_topic22 b) as6 +FROM tb_topic22 a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.Id as1, a.Clicks as2, a.TypeGuid as3, a.Title as4, a.CreateTime as5, (SELECT avg(b.Id) + FROM tb_topic22 b) as6 +FROM tb_topic22 a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime +FROM tb_topic22 a +WHERE (((cast(a.Id as varchar(8000))) in (SELECT b.Title + FROM tb_topic22 b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + + subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime +FROM tb_topic22 a +WHERE (((cast(a.Id as varchar(8000))) in ( SELECT * FROM (SELECT FIRST 10 b.Title + FROM tb_topic22 b) ftblmt50 )))", subquery); + subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 a__Type ON a__Type.Guid = a.TypeGuid", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentIn_AT a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 b ON b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 b ON b.Guid = a.TypeGuid AND b.Name = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 a__Type ON a__Type.Guid = a.TypeGuid AND a__Type.Name = 'xxx' LEFT JOIN TestTypeParentIn_AT a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId WHERE (a__Type__Parent.Id = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 a__Type ON a__Type.Guid = a.TypeGuid LEFT JOIN TestTypeParentIn_AT a__Type__Parent ON a__Type__Parent.Id = a__Type.ParentId", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a__Type.Guid, a__Type.ParentId, a__Type.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 a__Type ON a__Type.Guid = a.TypeGuid LEFT JOIN TestTypeParentIn_AT c ON c.Id = a__Type.ParentId", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, b.Guid, b.ParentId, b.Name, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo_T2 b ON a.TypeGuid = b.Guid LEFT JOIN TestTypeParentIn_AT c ON b.ParentId = c.Id", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22_T1 a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a) ftb UNION ALLSELECT * from (SELECT a.Id, a.Clicks, a.TypeGuid, a.Title, a.CreateTime FROM tb_topic22 a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM tb_topic22 a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM tb_topic22 a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + //select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.gbase.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.gbase.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.gbase.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.gbase.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.gbase.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.gbase.Insert(model4s).ExecuteAffrows()); + + var t0 = g.gbase.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.gbase.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.gbase.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.gbase.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.gbase.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.gbase.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.gbase.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.gbase.Insert(model1).ExecuteIdentity(); + + var t1 = g.gbase.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.gbase.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.gbase.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.gbase.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.gbase.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.gbase.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.gbase.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.gbase.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.gbase.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.gbase.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.gbase.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.gbase.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.gbase.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.gbase.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.gbase.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.gbase.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.gbase.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.gbase.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.gbase.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.gbase.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.gbase.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.gbase.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.gbase.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.gbase.Insert(song3).ExecuteIdentity(); + + g.gbase.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.gbase.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.gbase.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.gbase.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.gbase.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.gbase.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.gbase.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.gbase.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.gbase.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.gbase.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.gbase, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.gbase.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.gbase.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.gbase.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.gbase.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.gbase.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.gbase.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.gbase.Select().Count()); + g.gbase.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.gbase.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.gbase.Select().Count()); + Assert.Equal(3, g.gbase.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.gbase.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.gbase.Select().Count()); + g.gbase.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.gbase.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.gbase.Select().Count()); + Assert.Equal(3, g.gbase.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.gbase.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.gbase.Select().Count()); + g.gbase.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.gbase.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.gbase.Select().Count()); + Assert.Equal(3, g.gbase.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.gbase.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.gbase.Select().Count()); + g.gbase.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.gbase.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.gbase.Select().Count()); + Assert.Equal(5, g.gbase.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.gbase.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.gbase.Select().Count()); + g.gbase.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.gbase.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.gbase.Select().Count()); + Assert.Equal(5, g.gbase.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.gbase.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.gbase.Select().Count()); + g.gbase.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.gbase.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.gbase.Select().Count()); + Assert.Equal(5, g.gbase.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.gbase; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT FIRST 1 a.id, a.name FROM ToUpd1Pk a for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT FIRST 1 a.id, a.name FROM ToUpd1Pk a for update", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.gbase; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + + public int testint { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseUpdateTest.cs new file mode 100644 index 00000000..cb5094ba --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/Curd/GBaseUpdateTest.cs @@ -0,0 +1,234 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseUpdateTest + { + IUpdate update => g.gbase.Update(); + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "tb_topic_setsource")] + class Topic22 + { + [Column(IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.gbase.Update().ToSql()); + Assert.Equal("UPDATE tb_topic_insert SET Title='test' \r\nWHERE (Id IN (1,2))", g.gbase.Update(new[] { 1, 2 }).SetRaw("Title='test'").ToSql()); + Assert.Equal("UPDATE tb_topic_insert SET Title='test1' \r\nWHERE (Id = 1)", g.gbase.Update(new Topic { Id = 1, Title = "test" }).SetRaw("Title='test1'").ToSql()); + Assert.Equal("UPDATE tb_topic_insert SET Title='test1' \r\nWHERE (Id IN (1,2))", g.gbase.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("Title='test1'").ToSql()); + Assert.Equal("UPDATE tb_topic_insert SET Title='test1' \r\nWHERE (Id = 1)", g.gbase.Update(new { id = 1 }).SetRaw("Title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = NULL, Title = 'newtitle', CreateTime = '0001-01-01 00:00:00.000' WHERE (Id = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = CASE Id WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, Title = CASE Id WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, CreateTime = CASE Id WHEN 1 THEN '0001-01-01 00:00:00.000' WHEN 2 THEN '0001-01-01 00:00:00.000' WHEN 3 THEN '0001-01-01 00:00:00.000' WHEN 4 THEN '0001-01-01 00:00:00.000' WHEN 5 THEN '0001-01-01 00:00:00.000' WHEN 6 THEN '0001-01-01 00:00:00.000' WHEN 7 THEN '0001-01-01 00:00:00.000' WHEN 8 THEN '0001-01-01 00:00:00.000' WHEN 9 THEN '0001-01-01 00:00:00.000' WHEN 10 THEN '0001-01-01 00:00:00.000' END WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = CASE Id WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET CreateTime = '2020-01-01 00:00:00.000' WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.gbase.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE ts_source_mpk SET xx = CASE (id1 || '+' || id2) WHEN (1 || '+' || 7) THEN 'a1' WHEN (1 || '+' || 8) THEN 'b122' END WHERE ((id1 = 1 AND id2 = 7) OR (id1 = 1 AND id2 = 8))", sql); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceNoIdentity() + { + var fsql = g.gbase; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var sql = fsql.Update().SetSource(new Topic22 { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_setsource SET Clicks = NULL, Title = 'newtitle', CreateTime = '0001-01-01 00:00:00.000' WHERE (Id = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic22 { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.Equal(10, fsql.Insert(items).ExecuteAffrows()); + items[0].Clicks = null; + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_setsource SET Clicks = CASE Id WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, Title = CASE Id WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, CreateTime = CASE Id WHEN 1 THEN '0001-01-01 00:00:00.000' WHEN 2 THEN '0001-01-01 00:00:00.000' WHEN 3 THEN '0001-01-01 00:00:00.000' WHEN 4 THEN '0001-01-01 00:00:00.000' WHEN 5 THEN '0001-01-01 00:00:00.000' WHEN 6 THEN '0001-01-01 00:00:00.000' WHEN 7 THEN '0001-01-01 00:00:00.000' WHEN 8 THEN '0001-01-01 00:00:00.000' WHEN 9 THEN '0001-01-01 00:00:00.000' WHEN 10 THEN '0001-01-01 00:00:00.000' END WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_setsource SET Title = CASE Id WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_setsource SET CreateTime = '2020-01-01 00:00:00.000' WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE tssi01 SET tint = 10 WHERE (id = '00000000-0000-0000-0000-000000000000')", + g.gbase.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string Title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle' WHERE (Id = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new object[] { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle' WHERE (Id = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new[] { "Clicks", "CreateTime" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle' WHERE (Id = 1)", sql); + + var cols = new[] { "Clicks", "CreateTime" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle' WHERE (Id = 1)", sql); + + cols = new[] { "Clicks", "CreateTime" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle' WHERE (Id = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle' WHERE (Id = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle' WHERE (Id = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title = 'newtitle', CreateTime = '2020-01-01 00:00:00.000' WHERE (Id = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = trunc(nvl(Clicks, 0) * 10/1) WHERE (Id = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Id = (Id - 10) WHERE (Id = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = trunc(nvl(Clicks, 0) * 10/1) WHERE (Id = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Id = (Id - 10) WHERE (Id = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = trunc(Clicks * 10/1) WHERE (Id = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = case when CreateTime > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE (Id = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Id = 10 WHERE (Id = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = NULL WHERE (Id = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = NULL WHERE (Id = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET clicks = clicks + @incrClick WHERE (Id = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, Title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = 1, Title = 'xxx' WHERE (Id = 1)", sql); + + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["Title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Clicks = 1, Title = 'xxx' WHERE (Id = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("Title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title='newtitle' WHERE (Id = 1)", sql); + + sql = update.Where("id = @id", new { id = 1 }).SetRaw("Title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title='newtitle' WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("Title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title='newtitle' WHERE (Id = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("Title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE tb_topic_insert SET Title='newtitle' WHERE (Id IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.gbase.Update().ToSql()); + Assert.Equal("UPDATE tb_topicAsTable SET Title='test' \r\nWHERE (Id IN (1,2))", g.gbase.Update(new[] { 1, 2 }).SetRaw("Title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE tb_topicAsTable SET Title='test1' \r\nWHERE (Id = 1)", g.gbase.Update(new Topic { Id = 1, Title = "test" }).SetRaw("Title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE tb_topicAsTable SET Title='test1' \r\nWHERE (Id IN (1,2))", g.gbase.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("Title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE tb_topicAsTable SET Title='test1' \r\nWHERE (Id = 1)", g.gbase.Update(new { id = 1 }).SetRaw("Title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/ExtensionsAdo/GBaseAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/ExtensionsAdo/GBaseAdoTest.cs new file mode 100644 index 00000000..563c6be2 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/ExtensionsAdo/GBaseAdoTest.cs @@ -0,0 +1,73 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.gbase.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.gbase.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.gbase.Ado.ExecuteConnectTest()); + } + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.gbase.Ado.Query("select * from TB_TOPIC22"); + + var t4 = g.gbase.Ado.Query<(int, string, string)>("select * from TB_TOPIC22"); + + var t5 = g.gbase.Ado.Query("select * from TB_TOPIC22"); + + var t6 = g.gbase.Ado.Query("select * from TB_TOPIC22 where ID in @ids", new { ids = new[] { 1, 2, 3 } }); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.firebird.Ado.Query("select * from TB_TOPIC; select * from TB_TOPIC; select * from TB_TOPIC"); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/ConvertTest.cs new file mode 100644 index 00000000..19e04965 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBaseExpression +{ + public class ConvertTest + { + + ISelect select => g.gbase.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + 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()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/DateTimeTest.cs new file mode 100644 index 00000000..ae6892f0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/DateTimeTest.cs @@ -0,0 +1,642 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBaseExpression +{ + public class DateTimeTest + { + + ISelect select => g.gbase.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + 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)).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()); + + g.gbase.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"), 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 tt t").Replace(" ", " ").Replace(" ", " "), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } + + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //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 (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //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 (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //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 (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //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 (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + //data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //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 ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //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 ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //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 ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //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 ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(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 (dayofmonth(a__Type.`Time`) > dayofmonth(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 (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(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 (dayofyear(a__Type.`Time`) > dayofyear(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 (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(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 (month(a__Type.`Time`) > month(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 (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(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 (year(a__Type.`Time`) > year(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 (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(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 (hour(a__Type.`Time`) > hour(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 (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(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 (minute(a__Type.`Time`) > minute(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 (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(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 (second(a__Type.`Time`) > second(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 (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //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 (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //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 (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > 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_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > 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_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > 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_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > 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_add(a.`CreateTime`, interval (1) day) > 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_add(a__Type.`Time`, interval (1) day) > 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_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > 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_add(a.`CreateTime`, interval (1) hour) > 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_add(a__Type.`Time`, interval (1) hour) > 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_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > 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_add(a.`CreateTime`, interval (1) * 1000 microsecond) > 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_add(a__Type.`Time`, interval (1) * 1000 microsecond) > 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_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > 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_add(a.`CreateTime`, interval (1) minute) > 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_add(a__Type.`Time`, interval (1) minute) > 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_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > 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_add(a.`CreateTime`, interval (1) month) > 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_add(a__Type.`Time`, interval (1) month) > 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_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > 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_add(a.`CreateTime`, interval (1) second) > 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_add(a__Type.`Time`, interval (1) second) > 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_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > 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_add(a.`CreateTime`, interval (1) / 10 microsecond) > 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_add(a__Type.`Time`, interval (1) / 10 microsecond) > 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_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > 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_add(a.`CreateTime`, interval (1) year) > 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_add(a__Type.`Time`, interval (1) year) > 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_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).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_add(a.`CreateTime`, interval (1) year) = 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_add(a__Type.`Time`, interval (1) year) = 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_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //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_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //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_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //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 (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //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 (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), 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_add(a.`CreateTime`, interval (1) year) = 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_add(a__Type.`Time`, interval (1) year) = 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_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //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 (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //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 (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + //data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + //data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > 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 (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > 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 (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/MathTest.cs new file mode 100644 index 00000000..5a0f5c87 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/MathTest.cs @@ -0,0 +1,150 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBaseExpression +{ + public class MathTest + { + + ISelect select => g.gbase.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/OtherTest.cs new file mode 100644 index 00000000..0aacb521 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/OtherTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBaseExpression +{ + public class OtherTest + { + + ISelect select => g.gbase.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Int > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Int > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Int > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Int > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Int > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Int > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Int > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Int > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Int > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Int > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Int > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Int > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Int > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Int > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Int > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Int > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Int > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Int > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Int > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Int > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsPrimary = true)] + public Guid Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTime { get; set; } + + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeNullable { get; set; } + + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/StringTest.cs new file mode 100644 index 00000000..fb6a1e8b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/StringTest.cs @@ -0,0 +1,816 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBaseExpression +{ + public class StringTest + { + + ISelect select => g.gbase.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.gbase.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void StringJoin() + { + var fsql = g.gbase; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + //val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + //val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + //Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + //val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + //val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + //Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + + [Fact] + public void Format() + { + var item = g.gbase.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'||nvl((a.Id + 1), '')||'z-'||nvl(to_char(a.CreateTime,'YYYYMM'), '')||''||nvl(a.Title, '')||'' as1, ''||nvl((a.Id + 1), '')||'x'||nvl((a.Id + 1), '')||'z-'||nvl(to_char(a.CreateTime,'YYYYMM'), '')||''||nvl(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 Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.gbase.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}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||nvl((a.Id + 1), '')||'z-'||nvl(to_char(a.CreateTime,'YYYYMM'), '')||''||nvl(a.Title, '')||''||nvl(a.Title, '')||'' as1, ''||nvl((a.Id + 1), '')||'x'||nvl((a.Id + 1), '')||'z-'||nvl(to_char(a.CreateTime,'YYYYMM'), '')||''||nvl(a.Title, '')||''||nvl(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}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (coalesce(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/TimeSpanTest.cs new file mode 100644 index 00000000..970e9516 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/FirebirdExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.GBaseExpression +{ + public class TimeSpanTest + { + + ISelect select => g.gbase.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseAopTest.cs new file mode 100644 index 00000000..b5f50818 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.gbase.Aop.AuditValue += audit; + + g.gbase.Insert(item).ExecuteAffrows(); + + g.gbase.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseCodeFirstTest.cs new file mode 100644 index 00000000..071b4590 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseCodeFirstTest.cs @@ -0,0 +1,346 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseCodeFirstTest + { + [Fact] + public void InsertUpdateParameter() + { + var fsql = g.gbase; + fsql.CodeFirst.SyncStructure(); + var item = new ts_iupstr { id = Guid.NewGuid(), title = string.Join(",", Enumerable.Range(0, 2000).Select(a => "й")) }; + Assert.Equal(1, fsql.Insert(item).ExecuteAffrows()); + var find = fsql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(find.id, item.id); + Assert.Equal(find.title, item.title); + } + [Table(Name = "ts_iupstr_bak", DisableSyncStructure = true)] + class ts_iupstr + { + public Guid id { get; set; } + public string title { get; set; } + } + class ts_iupstr_bak + { + public Guid id { get; set; } + [Column(StringLength = -1)] + public string title { get; set; } + } + + [Fact] + public void Text_StringLength_1() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var str2 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й˰")); + + var item1 = new TS_TEXT02 { Data = str1, Data2 = str2 }; + Assert.Equal(1, g.gbase.Insert(item1).ExecuteAffrows()); + + var item2 = g.gbase.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + Assert.Equal(str2, item2.Data2); + + //NoneParameter + item1 = new TS_TEXT02 { Data = str1, Data2 = str2 }; + Assert.Equal(1, g.gbase.Insert(item1).NoneParameter().ExecuteAffrows()); + item2 = g.gbase.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + Assert.Equal(str2, item2.Data2); + //Assert.Throws(() => g.firebird.Insert(item1).NoneParameter().ExecuteAffrows()); + //Dynamic SQL Error + //SQL error code = -104 + //String literal with 159999 bytes exceeds the maximum length of 65535 bytes + } + class TS_TEXT02 + { + public Guid Id { get; set; } + [Column(StringLength = - 1)] + public string Data { get; set; } + [Column(StringLength = -1)] + public string Data2 { get; set; } + } + + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.gbase.Insert(item1).ExecuteAffrows()); + + var item2 = g.gbase.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.gbase.Insert(item1).NoneParameter().ExecuteAffrows()); + item2 = g.gbase.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + //Assert.Throws(() => g.firebird.Insert(item1).NoneParameter().ExecuteAffrows()); + //Dynamic SQL Error + //SQL error code = -104 + //String literal with 159999 bytes exceeds the maximum length of 65535 bytes + } + class TS_BLB01 + { + public Guid Id { get; set; } + public byte[] Data { get; set; } + } + [Fact] + public void StringLength() + { + var dll = g.gbase.CodeFirst.GetComparisonDDLStatements(); + g.gbase.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void ı_ֶ() + { + var sql = g.gbase.CodeFirst.GetComparisonDDLStatements<ı>(); + g.gbase.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.gbase.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.gbase.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.gbase.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.gbase.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.gbase.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.gbase.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.gbase.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] + public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.gbase.CodeFirst.GetComparisonDDLStatements(); + g.gbase.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index2", "group,index", false)] + class AddUniquesInfo + { + /// + /// + /// + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.gbase.CodeFirst.GetComparisonDDLStatements(); + + var id = g.gbase.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.firebird.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + var sql = g.gbase.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.gbase.Insert(); + ISelect select => g.gbase.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + insert.AppendData(item).ExecuteAffrows(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue + 1, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue + 1, + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue + 1, + ULong = long.MaxValue, + ULongNullable = ulong.MinValue + 1, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue + 1, + testFielLongNullable = long.MinValue + 1 + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + + insert.AppendData(item2).ExecuteAffrows(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = Guid.NewGuid(); + insert.NoneParameter().AppendData(item2).ExecuteAffrows(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsPrimary = true)] + public Guid Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTime { get; set; } + + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeNullable { get; set; } + + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseDbFirstTest.cs new file mode 100644 index 00000000..53a7013b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/GBaseDbFirstTest.cs @@ -0,0 +1,50 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.GBase +{ + public class GBaseDbFirstTest + { + [Fact] + public void GetDatabases() + { + } + + [Fact] + public void GetTablesByDatabase() + { + } + + [Fact] + public void GetTableByName() + { + var fsql = g.gbase; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + Assert.NotNull(t1); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + + [Fact] + public void ExistsTable() + { + var fsql = g.gbase; + try + { + fsql.Ado.ExecuteNonQuery("drop table test_existstb011"); + } + catch { } + Assert.False(fsql.DbFirst.ExistsTable("test_existstb011")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb011", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb011)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb011")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb011", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb011"); + } + class test_existstb011 + { + public Guid id { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..0d1e46a9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.GBaseMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.gbase; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/BoolTest.cs new file mode 100644 index 00000000..dd32892a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.GBaseMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.gbase; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..c542bec5 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.GBaseMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.gbase; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/EnumTest.cs new file mode 100644 index 00000000..ea847b1a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.GBaseMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.gbase; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.gbase; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.gbase; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.gbase; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/ToStringTest.cs new file mode 100644 index 00000000..b9f6adb0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/GBase/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.GBaseMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.gbase; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs new file mode 100644 index 00000000..90ea40d4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.GBase/g.cs @@ -0,0 +1,39 @@ +using IBM.Data.Informix; +using System; +using System.Collections.Generic; +using System.Data.Odbc; +using System.Diagnostics; +using System.Text; +using System.Threading; + +public class g +{ + + + static Lazy gbaseLazy = new Lazy(() => + { + var build = new OdbcConnectionStringBuilder(); + build.Driver = "GBase ODBC DRIVER (64-Bit)"; // 在系统中注册的驱动名称 + build.Add("Host", "192.168.164.134"); // 主机地址或者IP地址 + build.Add("Service", "9088"); // 数据库服务器的使用的端口号 + build.Add("Server", "gbase01"); // 数据库服务名称 + build.Add("Database", "testdb"); // 数据库名(DBNAME) + build.Add("Protocol", "onsoctcp"); // 网络协议名称 + build.Add("Uid", "gbasedbt"); // 用户 + build.Add("Pwd", "GBase123"); // 密码 + build.Add("Db_locale", "zh_CN.utf8"); // 数据库字符集 + build.Add("Client_locale", "zh_CN.utf8"); // 客户端字符集 + + return new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.GBase, build.ConnectionString) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build(); + }); + public static IFreeSql gbase => gbaseLazy.Value; + +} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 85835297..ca88f326 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1,12 +1,15 @@ using FreeSql.DataAnnotations; using FreeSql.Internal.Model; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using System.Text; using Xunit; +using FreeSql.Internal.CommonProvider; namespace FreeSql.Tests.Sqlite { @@ -147,6 +150,7 @@ namespace FreeSql.Tests.Sqlite var dt1 = select.Limit(10).ToDataTable(); var dt2 = select.Limit(10).ToDataTable("id, 111222"); var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + var dt4 = select.Limit(10).ToDataTableByPropertyName(new[] { "a.Id", "a.Type.Name", "Title", "clicks" }); } class TestDto { @@ -366,6 +370,9 @@ namespace FreeSql.Tests.Sqlite var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); var sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); + (query as Select0Provider)._tables.Where(a => a.Table.Type == typeof(TestTypeInfo)) + .First() + .Type = SelectTableInfoType.InnerJoin; query.ToList(); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); @@ -1233,7 +1240,7 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" //---- Select ---- var at0 = g.sqlite.Select() - .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.model2id <= model1.id) .ToList(); var at001 = g.sqlite.Select() @@ -1241,19 +1248,23 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .Where(a => a.model2id <= model1.id) .ToList(a => new { - a.model2id, a.childs, childs2 = a.childs + a.model2id, + a.childs, + childs2 = a.childs }); var at1 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.id <= model1.id) - .ToList(); + .ToList(); var at111 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.id <= model1.id) .ToList(a => new { - a.id, a.model2.childs, childs2 = a.model2.childs + a.id, + a.model2.childs, + childs2 = a.model2.childs }); var at2 = g.sqlite.Select() @@ -1267,7 +1278,9 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .Where(a => a.id <= model1.id) .ToList(a => new { - a.id, a.model2.childs, childs2 = a.model2.childs + a.id, + a.model2.childs, + childs2 = a.model2.childs }); var at00 = g.sqlite.Select() @@ -1279,7 +1292,9 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .Where(a => a.model2id <= model1.id) .ToList(a => new { - a.model2id, a.childs, childs2 = a.childs + a.model2id, + a.childs, + childs2 = a.childs }); var at11 = g.sqlite.Select() @@ -1290,9 +1305,11 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.id <= model1.id) .ToList(a => new - { - a.id, a.model2.childs, childs2 = a.model2.childs - }); + { + a.id, + a.model2.childs, + childs2 = a.model2.childs + }); var at22 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), @@ -1305,7 +1322,9 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .Where(a => a.id <= model1.id) .ToList(a => new { - a.id, a.model2.childs, childs2 = a.model2.childs + a.id, + a.model2.childs, + childs2 = a.model2.childs }); } @@ -1724,7 +1743,9 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) .ToList(a => new { - a.Id, a.Is_deleted, a.Tags + a.Id, + a.Is_deleted, + a.Tags }); } @@ -2481,6 +2502,33 @@ ORDER BY a__Parent.""Name""", sql); Assert.Equal(@"SELECT a.""id"", a.""name"", a.""no"", a.""status"" FROM ""ts_dyfilter_enum01"" a WHERE ((not((a.""name"") LIKE '%testname01') OR not((a.""no"") LIKE '%testname01') OR not((a.""id"") LIKE '%testname01') OR a.""status"" = 2))", sql); + + sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" +{ + ""Logic"" : ""Or"", + ""Filters"" : + [ + { + ""Field"" : ""MyRawSql FreeSql.Tests.Sqlite.DynamicFilterMyCustom,FreeSql.Tests"", + ""Operator"" : ""Custom"", + ""Value"" : ""(name,no) in (('testname01','testname01'))"" + }, + { + ""Field"" : ""no"", + ""Operator"" : ""NotEndsWith"", + ""Value"" : ""testname01"" + }, + { + ""Field"" : ""MyRawSql FreeSql.Tests.Sqlite.DynamicFilterMyCustom,FreeSql.Tests"", + ""Operator"" : ""Custom"", + ""Value"" : ""(id,status) in (('testname01','finished'))"" + }, + ] +} +")).ToSql(); + Assert.Equal(@"SELECT a.""id"", a.""name"", a.""no"", a.""status"" +FROM ""ts_dyfilter_enum01"" a +WHERE (((name,no) in (('testname01','testname01')) OR not((a.""no"") LIKE '%testname01') OR (id,status) in (('testname01','finished'))))", sql); } class ts_dyfilter_enum01 @@ -2492,4 +2540,37 @@ WHERE ((not((a.""name"") LIKE '%testname01') OR not((a.""no"") LIKE '%testname01 } public enum ts_dyfilter_enum01_status { staring, stoped, finished } } + + public class DynamicFilterMyCustom + { + [DynamicFilterCustom] + public static string MyRawSql(string value) => value; + + public static string TupleIn(string value) + { + var sb = new StringBuilder(); + var array = JArray.Parse(value); + var row = 0; + foreach(JObject item in array) + { + if (row++ == 0) + { + sb.Append("("); + var propNames = item.Properties().Select(a => a.Name); + sb.Append(string.Join(", ", propNames)); + sb.Append(") IN ("); + } + if (row == array.Count - 1) + { + sb.Append(")"); + } + if (row > 1) sb.Append(", "); + sb.Append("("); + var propValues = item.Values().Select(a => a?.ToString().Replace("'", "''")); //注入处理 + sb.Append(string.Join(", ", propValues)); + sb.Append(")"); + } + return sb.ToString(); + } + } } diff --git a/FreeSql.sln b/FreeSql.sln index a6d59db1..6a97cec2 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -101,7 +101,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.zh-CN.md = README.zh-CN.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.ClickHouse", "Providers\FreeSql.Provider.ClickHouse\FreeSql.Provider.ClickHouse.csproj", "{86C56235-5D37-4422-807B-B31681C7D01C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.ClickHouse", "Providers\FreeSql.Provider.ClickHouse\FreeSql.Provider.ClickHouse.csproj", "{86C56235-5D37-4422-807B-B31681C7D01C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.GBase", "Providers\FreeSql.Provider.GBase\FreeSql.Provider.GBase.csproj", "{BDE8EDC6-2646-45E0-A921-39CD1538A8C5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.GBase", "FreeSql.Tests\FreeSql.Tests.Provider.GBase\FreeSql.Tests.Provider.GBase.csproj", "{B887C0DA-01BE-4537-ADC1-92545AC85684}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -593,6 +597,30 @@ Global {86C56235-5D37-4422-807B-B31681C7D01C}.Release|x64.Build.0 = Release|Any CPU {86C56235-5D37-4422-807B-B31681C7D01C}.Release|x86.ActiveCfg = Release|Any CPU {86C56235-5D37-4422-807B-B31681C7D01C}.Release|x86.Build.0 = Release|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Debug|x64.Build.0 = Debug|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Debug|x86.ActiveCfg = Debug|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Debug|x86.Build.0 = Debug|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Release|Any CPU.Build.0 = Release|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Release|x64.ActiveCfg = Release|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Release|x64.Build.0 = Release|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Release|x86.ActiveCfg = Release|Any CPU + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5}.Release|x86.Build.0 = Release|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Debug|x64.ActiveCfg = Debug|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Debug|x64.Build.0 = Debug|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Debug|x86.ActiveCfg = Debug|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Debug|x86.Build.0 = Debug|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Release|Any CPU.Build.0 = Release|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Release|x64.ActiveCfg = Release|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Release|x64.Build.0 = Release|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Release|x86.ActiveCfg = Release|Any CPU + {B887C0DA-01BE-4537-ADC1-92545AC85684}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -627,6 +655,7 @@ Global {101B11D2-7780-4E14-9B72-77F5D69B3DF9} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {0DBAA21C-39B2-4AAD-A43D-88E67ED239D1} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {86C56235-5D37-4422-807B-B31681C7D01C} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {BDE8EDC6-2646-45E0-A921-39CD1538A8C5} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index f2c978ea..a8b3ef86 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -61,6 +61,12 @@ namespace FreeSql /// 注意:该类型不提供 DbFirst/CodeFirst 功能 /// Custom, - ClickHouse + + ClickHouse, + + /// + /// 天津南大通用数据技术股份有限公司成立于2004年,是国产数据库、大数据领域的知名企业,基于 Odbc 的实现 + /// + GBase } } diff --git a/FreeSql/DatabaseModel/DBColumnInfo.cs b/FreeSql/DatabaseModel/DBColumnInfo.cs index 1c5b9949..ffb297c6 100644 --- a/FreeSql/DatabaseModel/DBColumnInfo.cs +++ b/FreeSql/DatabaseModel/DBColumnInfo.cs @@ -45,9 +45,18 @@ namespace FreeSql.DatabaseModel /// public bool IsNullable { get; set; } /// + /// 备注,早期编码时少按了一个字母,请使用 Comment + /// + [Obsolete("早期编码时少按了一个字母,请使用 Comment")] + public string Coment + { + get => Comment; + set => Comment = value; + } + /// /// 备注 /// - public string Coment { get; set; } + public string Comment { get; set; } /// /// 数据库默认值 /// diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index d456c715..45882a22 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -140,6 +140,17 @@ namespace FreeSql return 0; } + /// + /// 注意:使用者自己承担【注入风险】 + /// + /// + /// + static bool InternalRawSql([RawValue] string sql) + { + expContext.Value.Result = sql; + return false; + } + #region 大小判断 /// /// 大于 > @@ -460,6 +471,15 @@ namespace FreeSql expContext.Result = $"list({expContext.ParsedContent["column"]},{expContext.ParsedContent["delimiter"]})"; return null; } + public static string StringJoinGBaseWmConcatText(object column, object delimiter) + { + if (expContext.ParsedContent["delimiter"] == "','") + expContext.Result = $"wm_concat_text({expContext.ParsedContent["column"]})"; + else + throw new NotImplementedException("GBase 暂时不支持逗号以外的分割符"); + //expContext.Result = $"replace(wm_concat_text({expContext.ParsedContent["column"]}), ',', {expContext.ParsedContent["delimiter"]})"; + return null; + } #endregion } } \ No newline at end of file diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 3f67a8a5..b306b417 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -418,9 +418,25 @@ public static partial class FreeSqlGlobalExtensions if (select._orm.CodeFirst.IsSyncStructureToLower) cteName = cteName.ToLower(); if (select._orm.CodeFirst.IsSyncStructureToUpper) cteName = cteName.ToUpper(); - switch (select._orm.Ado.DataType) //MySql5.6 + switch (select._orm.Ado.DataType) { - case DataType.MySql: + case DataType.GBase: + //select t.parentid, t.subid, level + //from a_test t + //start with subid = '7' + //connect by prior subid = parentid; + var gbsb = new StringBuilder(); + var gbsbWhere = select._where.ToString(); + select._where.Clear(); + if (gbsbWhere.StartsWith(" AND ")) gbsbWhere = gbsbWhere.Remove(0, 5); + gbsb.Append(select._tosqlAppendContent).Append(" \r\nstart with ").Append(gbsbWhere).Append(" \r\nconnect by prior "); + if (up) gbsb.Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)).Append(" = ").Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)); + else gbsb.Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)).Append(" = ").Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)); + var gbswstr = gbsb.ToString(); + gbsb.Clear(); + select.AsAlias((_, old) => $"{old} {gbswstr}"); + return select; + case DataType.MySql: //MySql5.6 case DataType.OdbcMySql: var mysqlConnectionString = select._orm.Ado?.ConnectionString ?? select._connection?.ConnectionString ?? ""; if (_dicMySqlVersion.TryGetValue(mysqlConnectionString, out var mysqlVersion) == false) @@ -504,11 +520,11 @@ JOIN {select._commonUtils.QuoteSqlName(tb.DbName)} a ON cte_tbc.cte_id = a.{sele } sql1ctePath = $"{sql1ctePath} as cte_path, "; } - var sql1 = select.ToSql($"0 as cte_level, {sql1ctePath}{select.GetAllFieldExpressionTreeLevel2().Field}").Trim(); + var sql1 = select.ToSql($"0 as cte_level, {sql1ctePath}{select.GetAllFieldExpressionTreeLevel2(false).Field}").Trim(); select._where.Clear(); select.As("wct2"); - var sql2Field = select.GetAllFieldExpressionTreeLevel2().Field; + var sql2Field = select.GetAllFieldExpressionTreeLevel2(false).Field; var sql2InnerJoinOn = up == false ? string.Join(" and ", tbref.Columns.Select((a, z) => $"wct2.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(a.Attribute.Name)}")) : string.Join(" and ", tbref.Columns.Select((a, z) => $"wct2.{select._commonUtils.QuoteSqlName(a.Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}")); @@ -580,6 +596,7 @@ JOIN {select._commonUtils.QuoteSqlName(tb.DbName)} a ON cte_tbc.cte_id = a.{sele case DataType.OdbcOracle: case DataType.Dameng: //递归 WITH 子句必须具有列别名列表 case DataType.OdbcDameng: + case DataType.GBase: nsselsb.Append($"(cte_level, {(pathSelector == null ? "" : "cte_path, ")}{sql2Field.Replace("wct2.", "")})"); break; } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4d45126e..28d8de44 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.1;netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9c849a52..ab20a387 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -515,6 +515,11 @@ + + 备注,早期编码时少按了一个字母,请使用 Comment + + + 备注 @@ -656,6 +661,11 @@ 注意:该类型不提供 DbFirst/CodeFirst 功能 + + + 天津南大通用数据技术股份有限公司成立于2004年,是国产数据库、大数据领域的知名企业,基于 Odbc 的实现 + + 获取 IDbConnection 对应的 IFreeSql 实例 @@ -1202,6 +1212,13 @@ + + + 注意:使用者自己承担【注入风险】 + + + + 大于 > @@ -1792,6 +1809,13 @@ + + + 执行SQL查询,返回 properties 指定的实体类属性,并以 DataTable 接收 + + 属性名:Name导航属性:Parent.Name多表:b.Name + + 以字典的形式返回查询结果 @@ -3172,177 +3196,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > @age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 可自定义解析表达式 @@ -4167,6 +4020,27 @@ 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 + + + 自定义解析,此时 Field 为反射信息,Value 为静态方法的参数(string) + 示范:{ Operator: "Custom", Field: "RawSql webapp1.DynamicFilterCustom,webapp1", Value: "(id,name) in ((1,'k'),(2,'m'))" } + 注意:使用者自己承担【注入风险】 + 静态方法定义示范: + namespace webapp1 + { + public class DynamicFilterCustom + { + [DynamicFilterCustom] + public static string RawSql(string value) => value; + } + } + + + + + 授权 DynamicFilter 支持 Custom 自定义解析 + + 是否放弃继续读取 @@ -4216,12 +4090,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4292,12 +4160,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 0bb2383f..79b27190 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -270,6 +270,11 @@ namespace FreeSql if (type == null) throwNotFind("FreeSql.Provider.ClickHouse.dll", "FreeSql.ClickHouse.ClickHouseProvider<>"); break; + case DataType.GBase: + type = Type.GetType("FreeSql.GBase.GBaseProvider`1,FreeSql.Provider.GBase")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.GBase.dll", "FreeSql.GBase.GBaseProvider<>"); + break; + default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory"); } } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index d17490da..1a3e6510 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -18,6 +18,7 @@ namespace FreeSql #if net40 #else Task ToDataTableAsync(string field = null, CancellationToken cancellationToken = default); + Task ToDataTableByPropertyNameAsync(string[] properties, CancellationToken cancellationToken = default); Task> ToDictionaryAsync(Func keySelector, CancellationToken cancellationToken = default); Task> ToDictionaryAsync(Func keySelector, Func elementSelector, CancellationToken cancellationToken = default); Task> ToListAsync(bool includeNestedMembers = false, CancellationToken cancellationToken = default); @@ -72,6 +73,12 @@ namespace FreeSql /// /// DataTable ToDataTable(string field = null); + /// + /// 执行SQL查询,返回 properties 指定的实体类属性,并以 DataTable 接收 + /// + /// 属性名:Name导航属性:Parent.Name多表:b.Name + /// + DataTable ToDataTableByPropertyName(string[] properties); /// /// 以字典的形式返回查询结果 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b4c8352f..305dd76f 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1011,6 +1011,7 @@ namespace FreeSql.Internal case DataType.OdbcOracle: case DataType.Dameng: case DataType.OdbcDameng: + case DataType.GBase: break; default: fsqlSelect0._limit = 1; //#462 ORACLE rownum <= 2 会影响索引变慢 @@ -1305,6 +1306,7 @@ namespace FreeSql.Internal { case DataType.MySql: case DataType.OdbcMySql: + case DataType.GBase: if (exp3.Method.Name == "ToList") return $"( SELECT * FROM ({sqlFirst.Replace(" \r\n", " \r\n ")}) ftblmt50 )"; break; @@ -1877,6 +1879,7 @@ namespace FreeSql.Internal { if (obj == null) return "NULL"; var paramName = $"exp_{dbParams.Count}"; + if (_common._orm?.Ado.DataType == DataType.GBase) paramName = "?"; var parm = _common.AppendParamter(dbParams, paramName, mapColumn, mapType ?? mapColumn?.Attribute.MapType ?? obj?.GetType(), mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); return _common.QuoteParamterName(paramName); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 70036198..550ed7fe 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -111,6 +111,7 @@ namespace FreeSql.Internal.CommonProvider { case DataType.Oracle: case DataType.OdbcOracle: + case DataType.GBase: ExecuteNonQuery(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout); return true; case DataType.Firebird: diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 941e6ae9..011127c5 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -25,6 +25,7 @@ namespace FreeSql.Internal.CommonProvider { case DataType.Oracle: case DataType.OdbcOracle: + case DataType.GBase: await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout, null, cancellationToken); return true; case DataType.Firebird: @@ -476,7 +477,7 @@ namespace FreeSql.Internal.CommonProvider public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken); public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken); public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); - public async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) + async public Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 86f228ce..11bb8b85 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -182,6 +182,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.Oracle: case DataType.OdbcDameng: case DataType.Dameng: + case DataType.GBase: sb.Append(" FROM dual"); break; case DataType.Firebird: diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 1c4785a2..58326a91 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -352,6 +352,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.Oracle: case DataType.OdbcOracle: case DataType.Firebird: + case DataType.GBase: break; default: _select = "SELECT "; @@ -407,6 +408,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.Oracle: case DataType.OdbcOracle: case DataType.Firebird: + case DataType.GBase: break; default: var beforeSql = this._select; @@ -440,6 +442,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.Oracle: case DataType.OdbcOracle: case DataType.Firebird: + case DataType.GBase: break; default: var beforeSql = this._select; @@ -544,17 +547,35 @@ namespace FreeSql.Internal.CommonProvider { if (string.IsNullOrEmpty(fi.Field) == false) { - Expression exp = ConvertStringPropertyToExpression(fi.Field); + Expression exp = null; switch (fi.Operator) { + case DynamicFilterOperator.Custom: + var fiValueCustomArray = fi.Field?.ToString().Split(new[] { ' ' }, 2); + if (fiValueCustomArray.Length != 2) throw new ArgumentException("Custom 要求 Field 应该空格分割,并且长度为 2,格式:{静态方法名}{空格}{反射信息}"); + if (string.IsNullOrWhiteSpace(fiValueCustomArray[0])) throw new ArgumentException("Custom {静态方法名}不能为空,格式:{静态方法名}{空格}{反射信息}"); + if (string.IsNullOrWhiteSpace(fiValueCustomArray[1])) throw new ArgumentException("Custom {反射信息}不能为空,格式:{静态方法名}{空格}{反射信息}"); + var fiValue1Type = Type.GetType(fiValueCustomArray[1]); + if (fiValue1Type == null) throw new ArgumentException($"Custom 找不到对应的{{反射信息}}:{fiValueCustomArray[1]}"); + var fiValue0Method = fiValue1Type.GetMethod(fiValueCustomArray[0], new Type[] { typeof(string) }); + if (fiValue0Method == null) throw new ArgumentException($"Custom 找不到对应的{{静态方法名}}:{fiValueCustomArray[0]}"); + if (MethodIsDynamicFilterCustomAttribute(fiValue0Method) == false) throw new ArgumentException($"Custom 对应的{{静态方法名}}:{fiValueCustomArray[0]} 未设置 [DynamicFilterCustomAttribute] 特性"); + var fiValue0MethodReturn = fiValue0Method?.Invoke(null, new object[] { fi.Value?.ToString() })?.ToString(); + exp = Expression.Call(typeof(SqlExt).GetMethod("InternalRawSql", BindingFlags.NonPublic | BindingFlags.Static), Expression.Constant(fiValue0MethodReturn, typeof(string))); + break; + case DynamicFilterOperator.Contains: case DynamicFilterOperator.StartsWith: case DynamicFilterOperator.EndsWith: case DynamicFilterOperator.NotContains: case DynamicFilterOperator.NotStartsWith: case DynamicFilterOperator.NotEndsWith: + exp = ConvertStringPropertyToExpression(fi.Field); if (exp.Type != typeof(string)) exp = Expression.TypeAs(exp, typeof(string)); break; + default: + exp = ConvertStringPropertyToExpression(fi.Field); + break; } switch (fi.Operator) { @@ -579,7 +600,7 @@ namespace FreeSql.Internal.CommonProvider if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 要求 Value 应该逗号分割,并且长度为 2"); exp = Expression.AndAlso( Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[0]), exp.Type)), - Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[1]), exp.Type))); + Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[1]), exp.Type))); break; case DynamicFilterOperator.DateRange: var fiValueDateRangeArray = getFiListValue(); @@ -676,6 +697,21 @@ namespace FreeSql.Internal.CommonProvider string.IsNullOrEmpty(testFilter.Value?.ToString()); } } + static ConcurrentDictionary _dicMethodIsDynamicFilterCustomAttribute = new ConcurrentDictionary(); + static bool MethodIsDynamicFilterCustomAttribute(MethodInfo method) => _dicMethodIsDynamicFilterCustomAttribute.GetOrAdd(method, m => + { + object[] attrs = null; + try + { + attrs = m.GetCustomAttributes(false).ToArray(); //.net core 反射存在版本冲突问题,导致该方法异常 + } + catch { } + + var dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.Name == "DynamicFilterCustomAttribute"; + }).FirstOrDefault(); + return dyattr != null; + }); public TSelect DisableGlobalFilter(params string[] name) { @@ -722,6 +758,7 @@ namespace FreeSql.Internal.CommonProvider break; case DataType.Sqlite: break; + case DataType.GBase: case DataType.ShenTong: //神通测试中发现,不支持 nowait _tosqlAppendContent = $"{_tosqlAppendContent} for update"; break; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 06c59d5c..89f4ea05 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -19,6 +19,25 @@ namespace FreeSql.Internal.CommonProvider { partial class Select0Provider { + public DataTable ToDataTableByPropertyName(string[] properties) + { + if (properties?.Any() != true) throw new ArgumentException($"properties 参数不能为空"); + var sbfield = new StringBuilder(); + for (var propIdx = 0; propIdx < properties.Length; propIdx++) + { + var property = properties[propIdx]; + var exp = ConvertStringPropertyToExpression(property); + if (exp == null) throw new Exception($"{property} 属性名无法找到"); + var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null); + if (propIdx > 0) sbfield.Append(", "); + sbfield.Append(field); + //if (field != property) + sbfield.Append(_commonUtils.FieldAsAlias(_commonUtils.QuoteSqlName("test").Replace("test", property))); + } + var sbfieldStr = sbfield.ToString(); + sbfield.Clear(); + return ToDataTable(sbfieldStr); + } public DataTable ToDataTable(string field = null) { DataTable ret = null; @@ -514,7 +533,7 @@ namespace FreeSql.Internal.CommonProvider }); } static EventHandler _OldAuditDataReaderHandler; - public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2() + public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2(bool isRereadSql = true) { if (_selectExpression != null) //ToSql { @@ -530,7 +549,7 @@ namespace FreeSql.Internal.CommonProvider _OldAuditDataReaderHandler = _orm.Aop.AuditDataReaderHandler; //清除单表 ExppressionTree _dicGetAllFieldExpressionTree.TryRemove($"{_orm.Ado.DataType}-{_tables[0].Table.DbName}-{_tables[0].Table.CsName}-{_tables[0].Alias}-{_tables[0].Type}", out var oldet); } - return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Table.CsName}-{a.Alias}-{a.Type}")), s => + return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Table.CsName}-{a.Alias}-{a.Type}-{(isRereadSql ? 1 : 0)}")), s => { var tb1 = _tables.First().Table; var type = tb1.TypeLazy ?? tb1.Type; @@ -564,7 +583,8 @@ namespace FreeSql.Internal.CommonProvider { //普通字段 if (index > 0) field.Append(", "); var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.RereadColumn(col, $"{tb.Alias}.{quoteName}")); + if (isRereadSql) field.Append(_commonUtils.RereadColumn(col, $"{tb.Alias}.{quoteName}")); + else field.Append($"{tb.Alias}.{quoteName}"); ++index; if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); @@ -587,7 +607,8 @@ namespace FreeSql.Internal.CommonProvider { if (index > 0) field.Append(", "); var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); - field.Append(_commonUtils.RereadColumn(col2, $"{tb2.Alias}.{quoteName}")); + if (isRereadSql) field.Append(_commonUtils.RereadColumn(col2, $"{tb2.Alias}.{quoteName}")); + else field.Append($"{tb2.Alias}.{quoteName}"); ++index; ++otherindex; if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); @@ -900,6 +921,25 @@ namespace FreeSql.Internal.CommonProvider #region Async #if net40 #else + public Task ToDataTableByPropertyNameAsync(string[] properties, CancellationToken cancellationToken) + { + if (properties?.Any() != true) throw new ArgumentException($"properties 参数不能为空"); + var sbfield = new StringBuilder(); + for (var propIdx = 0; propIdx < properties.Length; propIdx++) + { + var property = properties[propIdx]; + var exp = ConvertStringPropertyToExpression(property); + if (exp == null) throw new Exception($"{property} 属性名无法找到"); + var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null); + if (propIdx > 0) sbfield.Append(", "); + sbfield.Append(field); + //if (field != property) + sbfield.Append(_commonUtils.FieldAsAlias(_commonUtils.QuoteSqlName("test").Replace("test", property))); + } + var sbfieldStr = sbfield.ToString(); + sbfield.Clear(); + return ToDataTableAsync(sbfieldStr, cancellationToken); + } async public Task ToDataTableAsync(string field, CancellationToken cancellationToken) { DataTable ret = null; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 757aaff1..2f0e0703 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -159,6 +159,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.OdbcOracle: case DataType.Dameng: case DataType.OdbcDameng: //Oracle、Dameng 分组时,嵌套分页 + case DataType.GBase: isNestedPageSql = true; break; default: diff --git a/FreeSql/Internal/Model/DynamicFilterInfo.cs b/FreeSql/Internal/Model/DynamicFilterInfo.cs index 060d772b..7b025e76 100644 --- a/FreeSql/Internal/Model/DynamicFilterInfo.cs +++ b/FreeSql/Internal/Model/DynamicFilterInfo.cs @@ -120,6 +120,28 @@ namespace FreeSql.Internal.Model /// not in (1,2,3) /// 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 /// - NotAny + NotAny, + + /// + /// 自定义解析,此时 Field 为反射信息,Value 为静态方法的参数(string) + /// 示范:{ Operator: "Custom", Field: "RawSql webapp1.DynamicFilterCustom,webapp1", Value: "(id,name) in ((1,'k'),(2,'m'))" } + /// 注意:使用者自己承担【注入风险】 + /// 静态方法定义示范: + /// namespace webapp1 + /// { + /// public class DynamicFilterCustom + /// { + /// [DynamicFilterCustom] + /// public static string RawSql(string value) => value; + /// } + /// } + /// + Custom } + + /// + /// 授权 DynamicFilter 支持 Custom 自定义解析 + /// + [AttributeUsage(AttributeTargets.Method)] + public class DynamicFilterCustomAttribute : Attribute { } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 9db2a0c3..a4b43ca4 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -204,6 +204,36 @@ namespace FreeSql.Internal // else if (Math.Abs(dt.Subtract(DateTime.UtcNow).TotalSeconds) < 60) // col.DbDefaultValue = common.NowUtc; //} + + if (common._orm.Ado.DataType == DataType.GBase) + { + if (colattr.IsIdentity == true) + { + var colType = col.CsType.NullableTypeOrThis(); + if (colType == typeof(int) || colType == typeof(uint)) + colattr.DbType = "SERIAL"; + else if (colType == typeof(long) || colType == typeof(ulong)) + colattr.DbType = "SERIAL8"; + } + if (colattr.MapType.NullableTypeOrThis() == typeof(DateTime)) + { + if (colattr._Precision == null) + { + colattr.DbType = "DATETIME YEAR TO FRACTION(3)"; + colattr.Precision = 3; + col.DbPrecision = 3; + } + else if (colattr._Precision == 0) + { + colattr.DbType = "DATETIME YEAR TO SECOND"; + } + else if (colattr._Precision > 0) + { + colattr.DbType = $"DATETIME YEAR TO FRACTION({colattr.Precision})"; + col.DbPrecision = (byte)colattr.Precision; + } + } + } if (colattr.ServerTime != DateTimeKind.Unspecified && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis())) { var commonNow = common.Now; @@ -283,6 +313,10 @@ namespace FreeSql.Internal if (strlen < 0) colattr.DbType = "BLOB SUB_TYPE 1"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; + case DataType.GBase: + if (strlen < 0) colattr.DbType = "TEXT"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; } } if (colattr.MapType == typeof(byte[]) && colattr.IsVersion == true) colattr.StringLength = 16; @@ -330,6 +364,9 @@ namespace FreeSql.Internal case DataType.Firebird: colattr.DbType = "BLOB"; break; + case DataType.GBase: + colattr.DbType = "BYTE"; + break; } } if (colattr.MapType.NullableTypeOrThis() == typeof(decimal) && (colattr.Precision > 0 || colattr.Scale > 0)) @@ -1352,6 +1389,7 @@ namespace FreeSql.Internal switch (orm.Ado.DataType) { case DataType.Dameng: //OdbcDameng 不会报错 + case DataType.GBase: if (dr.IsDBNull(index)) return null; break; } diff --git a/Providers/FreeSql.Provider.ClickHouse/ClickHouseDbFirst.cs b/Providers/FreeSql.Provider.ClickHouse/ClickHouseDbFirst.cs index 92e57371..bbb44fff 100644 --- a/Providers/FreeSql.Provider.ClickHouse/ClickHouseDbFirst.cs +++ b/Providers/FreeSql.Provider.ClickHouse/ClickHouseDbFirst.cs @@ -299,7 +299,7 @@ where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseI DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj index 43b24148..9527eff2 100644 --- a/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj +++ b/Providers/FreeSql.Provider.ClickHouse/FreeSql.Provider.ClickHouse.csproj @@ -3,7 +3,7 @@ netstandard2.1 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin;ChenBo FreeSql 数据库实现,基于 ClickHouse.Client Ado.net diff --git a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj index aa0935a0..b00668bd 100644 --- a/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj +++ b/Providers/FreeSql.Provider.Custom/FreeSql.Provider.Custom.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库自定义适配,访问所有数据库 diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index 613dbda5..148c5148 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -406,7 +406,7 @@ where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs b/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs index 7774195f..24931172 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs @@ -48,15 +48,19 @@ public static partial class FreeSqlDamengGlobalExtensions { if (insert.InternalConnection == null && insert.InternalTransaction == null) { - using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) - { - using (var bulkCopy = copyOptions == DmBulkCopyOptions.Default ? - new DmBulkCopy(conn.Value as DmConnection) : - new DmBulkCopy(conn.Value as DmConnection, copyOptions, insert.InternalTransaction as DmTransaction)) - { + if (insert._orm.Ado?.TransactionCurrentThread != null) + using (var bulkCopy = new DmBulkCopy(insert._orm.Ado.TransactionCurrentThread.Connection as DmConnection, copyOptions, insert._orm.Ado.TransactionCurrentThread as DmTransaction)) writeToServer(bulkCopy); + else + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + using (var bulkCopy = copyOptions == DmBulkCopyOptions.Default ? + new DmBulkCopy(conn.Value as DmConnection) : + new DmBulkCopy(conn.Value as DmConnection, copyOptions, insert.InternalTransaction as DmTransaction)) + { + writeToServer(bulkCopy); + } } - } } else if (insert.InternalTransaction != null) { diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index e5725ec1..cd41b097 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs b/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs index fa7fb0f0..94929e43 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs @@ -267,7 +267,7 @@ order by a.rdb$relation_name, a.rdb$field_position DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 73b5ffa9..823f2770 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs new file mode 100644 index 00000000..7e9f7b90 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseDelete.cs @@ -0,0 +1,32 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.GBase.Curd +{ + + class GBaseDelete : Internal.CommonProvider.DeleteProvider + { + public GBaseDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + throw new NotImplementedException(); + } + +#if net40 +#else + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsert.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsert.cs new file mode 100644 index 00000000..a6bf0ed5 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsert.cs @@ -0,0 +1,155 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.GBase.Curd +{ + + class GBaseInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public GBaseInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(1, 999); + + public override string ToSql() + { + if (_source?.Count <= 1) return base.ToSqlValuesOrSelectUnionAll(); + var sql = base.ToSqlValuesOrSelectUnionAllExtension102(false, null, (rowd, idx, sb) => sb.Append(" FROM dual")); + var validx = sql.IndexOf(") SELECT "); + if (validx == -1) throw new ArgumentException("找不到 SELECT"); + return new StringBuilder() + .Insert(0, sql.Substring(0, validx + 1)) + .Append("\r\nSELECT * FROM (\r\n") + .Append(sql.Substring(validx + 1)) + .Append("\r\n) ftbtmp") + .ToString(); + } + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var identityType = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault()?.CsType.NullableTypeOrThis(); + var identitySql = ""; + if (identityType != null) + { + if (identityType == typeof(int) || identityType == typeof(uint)) identitySql = "SELECT dbinfo('sqlca.sqlerrd1') FROM dual"; + else if (identityType == typeof(long) || identityType == typeof(ulong)) identitySql = "SELECT dbinfo('serial8') FROM dual"; + } + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, $"; {identitySql};"), _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + long ret = 0; + Exception exception = null; + var isUseConnection = _connection != null; + try + { + if (isUseConnection == false) + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _connection = conn.Value; + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + if (string.IsNullOrWhiteSpace(identitySql) == false) + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, identitySql, _commandTimeout, _params)), out ret); + } + } + else + { + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + if (string.IsNullOrWhiteSpace(identitySql) == false) + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, identitySql, _commandTimeout, _params)), out ret); + } + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (isUseConnection == false) _connection = null; + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + protected override List RawExecuteInserted() + { + throw new NotImplementedException(); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(1, 1000, cancellationToken); + + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var identityType = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault()?.CsType.NullableTypeOrThis(); + var identitySql = ""; + if (identityType != null) + { + if (identityType == typeof(int) || identityType == typeof(uint)) identitySql = "SELECT dbinfo('sqlca.sqlerrd1') FROM dual"; + else if (identityType == typeof(long) || identityType == typeof(ulong)) identitySql = "SELECT dbinfo('serial8') FROM dual"; + } + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, $"; {identitySql};"), _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + long ret = 0; + Exception exception = null; + var isUseConnection = _connection != null; + try + { + if (isUseConnection == false) + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _connection = conn.Value; + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + if (string.IsNullOrWhiteSpace(identitySql) == false) + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, identitySql, _commandTimeout, _params)), out ret); + } + } + else + { + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + if (string.IsNullOrWhiteSpace(identitySql) == false) + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, identitySql, _commandTimeout, _params)), out ret); + } + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (isUseConnection == false) _connection = null; + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs new file mode 100644 index 00000000..b54366b0 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs @@ -0,0 +1,72 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.GBase.Curd +{ + + class GBaseInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public GBaseInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + if (_doNothing == false && cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? + $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseSelect.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseSelect.cs new file mode 100644 index 00000000..daf5a217 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseSelect.cs @@ -0,0 +1,214 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.GBase.Curd +{ + + class GBaseSelect : FreeSql.Internal.CommonProvider.Select1Provider + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereGlobalFilter.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + + if (_limit > 0 && _skip > 0) sb.Append("SKIP ").Append(_skip).Append(" FIRST ").Append(_limit).Append(" "); + else if (_skip > 0) sb.Append("SKIP ").Append(_skip).Append(" "); + else if (_limit > 0) sb.Append("FIRST ").Append(_limit).Append(" "); + + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND ").Append(_tables[0].Cascade); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new GBaseSelect(_orm, _commonUtils, _commonExpression, null); GBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select10Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + + class GBaseSelect : FreeSql.Internal.CommonProvider.Select11Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select12Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select13Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select14Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select15Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class GBaseSelect : FreeSql.Internal.CommonProvider.Select16Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public GBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => GBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } +} + diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseUpdate.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseUpdate.cs new file mode 100644 index 00000000..20eb39b4 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseUpdate.cs @@ -0,0 +1,78 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.GBase.Curd +{ + + class GBaseUpdate : Internal.CommonProvider.UpdateProvider + { + + public GBaseUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (primarys.Length == 1) + { + var pk = primarys.First(); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) caseWhen.Append(" || '+' || "); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", primarys[0].GetDbValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) sb.Append(" || '+' || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); + ++pkidx; + } + sb.Append(")"); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj new file mode 100644 index 00000000..47a4d5fa --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/FreeSql.Provider.GBase.csproj @@ -0,0 +1,39 @@ + + + + netstandard2.0 + 3.0.100 + true + FreeSql;GBase + FreeSql 数据库实现,基于 南大通用 8.0 + https://github.com/dotnetcore/FreeSql + https://github.com/dotnetcore/FreeSql + git + MIT + FreeSql;ORM;GBase;南大通用 + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + + + + + + Always + + + + + + + + + + + + diff --git a/Providers/FreeSql.Provider.GBase/GBaseAdo/GBaseAdo.cs b/Providers/FreeSql.Provider.GBase/GBaseAdo/GBaseAdo.cs new file mode 100644 index 00000000..bcdea701 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseAdo/GBaseAdo.cs @@ -0,0 +1,93 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.GBase +{ + class GBaseAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + + public GBaseAdo() : base(DataType.GBase, null, null) { } + public GBaseAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.GBase, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.GBase, connectionFactory); + MasterPool = pool; + _CreateCommandConnection = pool.TestConnection; + return; + } + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new GBaseConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new GBaseConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + { + if (mapColumn?.DbPrecision > 0) + return string.Concat("'", ((DateTime)param).ToString($"yyyy-MM-dd HH:mm:ss.{"f".PadRight(mapColumn.DbPrecision, 'f')}"), "'"); + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'"); + } + else if (param is TimeSpan || param is TimeSpan?) + { + var ts = (TimeSpan)param; + return $"interval({ts.Days} {ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}) day(9) to fraction"; + } + else if (param is byte[]) + return $"x'{CommonUtils.BytesSqlRaw(param as byte[])}'"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + DbConnection _CreateCommandConnection; + public override DbCommand CreateCommand() + { + if (_CreateCommandConnection != null) + { + var cmd = _CreateCommandConnection.CreateCommand(); + cmd.Connection = null; + return cmd; + } + return new OdbcCommand(); + } + + public override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + var rawPool = pool as GBaseConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.GBase/GBaseAdo/GBaseConnectionPool.cs b/Providers/FreeSql.Provider.GBase/GBaseAdo/GBaseConnectionPool.cs new file mode 100644 index 00000000..2bf9e8c7 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseAdo/GBaseConnectionPool.cs @@ -0,0 +1,236 @@ +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.GBase +{ + + class GBaseConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public GBaseConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + var policy = new GBaseConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + try { if (obj.Value.Ping() == false) obj.Value.Open(); } catch { base.SetUnavailable(exception); } + } + base.Return(obj, isRecreate); + } + } + + class GBaseConnectionPoolPolicy : IPolicy + { + + internal GBaseConnectionPool _pool; + public string Name { get; set; } = "GBase IfxConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1 from dual"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.GBase/GBaseCodeFirst.cs b/Providers/FreeSql.Provider.GBase/GBaseCodeFirst.cs new file mode 100644 index 00000000..250ace61 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseCodeFirst.cs @@ -0,0 +1,213 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using FreeSql.DataAnnotations; +using FreeSql.Internal.ObjectPool; +using System.Data.Common; +using System.Data.Odbc; + +namespace FreeSql.GBase +{ + + class GBaseCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public GBaseCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(sbyte).FullName, CsToDb.New(OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, "integer","integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, "integer", "integer", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, "bigint", "bigint", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, "integer","integer NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, "integer", "integer", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, "bigint", "bigint", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Decimal, "decimal","decimal(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(20,0)", false, true, null) }, + + { typeof(float).FullName, CsToDb.New(OdbcType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, "real", "real", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, "float","float NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, "float", "float", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + + { typeof(TimeSpan).FullName, CsToDb.New(OdbcType.Time, "interval day to fraction","interval day(3) to fraction(3) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OdbcType.Time, "interval day to fraction", "interval day(3) to fraction(3) NULL",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "datetime year to fraction", "datetime year to fraction(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "datetime year to fraction", "datetime year to fraction(3)", false, true, null) }, + + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "boolean","boolean NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "boolean","boolean", null, true, null) }, + { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "byte", "byte", false, null, new byte[0]) }, + + { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "char(36)", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "char(36)", "char(36)", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + var info = GetDbInfoNoneArray(type); + if (info == null) return null; + return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue); + } + CsToDb GetDbInfoNoneArray(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc; + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(OdbcType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.Int, "integer", $"integer{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return newItem; + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + Object conn = null; + string database = null; + + try + { + conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + database = conn.Value.Database; + + var sb = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } + + if (string.Compare(tbname[0], database, true) != 0) //创建数据库 + { + try + { + LocalExecuteScalar(tbname[0], $" select first 1 1 from syscolcomms"); + } + catch + { + sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\n"); + } + } + + //创建表 + var createTableName = _commonUtils.QuoteSqlName(tbname[0], tbname[1]); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n)"); + sb.Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname.Last()}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName(tbname.Last())).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + continue; + } + return sb.Length == 0 ? null : sb.ToString(); + } + finally + { + try + { + if (string.IsNullOrEmpty(database) == false) + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } + catch + { + _orm.Ado.MasterPool.Return(conn, true); + } + } + + object LocalExecuteScalar(string db, string sql) + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + } + } + + public override int ExecuteDDLStatements(string ddl) + { + if (string.IsNullOrEmpty(ddl)) return 0; + var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); + + if (scripts.Any() == false) return 0; + + var affrows = 0; + foreach (var script in scripts) + affrows += base.ExecuteDDLStatements(script); + return affrows; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.GBase/GBaseDbFirst.cs b/Providers/FreeSql.Provider.GBase/GBaseDbFirst.cs new file mode 100644 index 00000000..25eb2aef --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseDbFirst.cs @@ -0,0 +1,201 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Data.Odbc; + +namespace FreeSql.GBase +{ + class GBaseDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public GBaseDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetOdbcType(column); + OdbcType GetOdbcType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + OdbcType ret = OdbcType.VarChar; + switch (dbtype.ToLower().TrimStart('_')) + { + case "int8": + case "serial8": + case "bigserial": + case "bigint": ret = OdbcType.BigInt; break; + case "byte": + case "blob": ret = OdbcType.VarBinary; break; + case "nchar": ret = OdbcType.NChar; break; + case "char": + case "character": ret = OdbcType.Char; break; + case "date": ret = OdbcType.Date; break; + case "dec": + case "decimal": ret = OdbcType.Decimal; break; + case "double": + case "double precision": + case "float": ret = OdbcType.Double; break; + case "real": + case "smallfloat": ret = OdbcType.Real; break; + case "serial": + case "integer": + case "int": ret = OdbcType.Int; break; + case "numeric": + case "numeric precision": ret = OdbcType.Decimal; break; + case "smallint": ret = OdbcType.SmallInt; break; + case "interval": ret = OdbcType.Time; break; + case "datetime": + case "timestamp": ret = OdbcType.DateTime; break; + case "varchar": + case "char varying": + case "character varying": ret = OdbcType.VarChar; break; + case "nvarchar": ret = OdbcType.NVarChar; break; + + case "text": ret = OdbcType.Text; break; + case "boolean": ret = OdbcType.Bit; break; + case "char(36)": ret = OdbcType.UniqueIdentifier; break; + } + return ret; + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OdbcType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OdbcType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)OdbcType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { (int)OdbcType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)OdbcType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)OdbcType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)OdbcType.VarBinary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)OdbcType.UniqueIdentifier, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + throw new NotImplementedException(); + } + + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (ignoreCase) tbname = tbname.Select(a => a.ToUpper()).ToArray(); + var sql = $" select 1 from systables where tabtype='T' and {(ignoreCase ? "upper(trim(tabname))" : "trim(tabname)")} = {_commonUtils.FormatSql("{0}", tbname.Last())}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) + { + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (ignoreCase) tbname = tbname.Select(a => a.ToUpper()).ToArray(); + } + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = @" +select +a.""owner"" || a.tabname as id, +trim(a.""owner"") as owner, +trim(a.tabname) as name, +trim(b.comments) as comment, +a.tabtype as type +from systables a +left join syscomments b on b.tabname = a.tabname +where a.tabtype in ('T', 'V')" + (tbname == null ? "" : $" and {(ignoreCase ? "upper(trim(a.tabname))" : "trim(a.tabname)")} = {_commonUtils.FormatSql("{0}", tbname.Last())}"); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + DbTableType type = DbTableType.TABLE; + switch (string.Concat(row[4])) + { + case "V": type = DbTableType.VIEW; break; + } + if (database?.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + loc1.Add(loc2[table_id]); + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + //todo: ... + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.GBase/GBaseExpression.cs b/Providers/FreeSql.Provider.GBase/GBaseExpression.cs new file mode 100644 index 00000000..f76a78f4 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseExpression.cs @@ -0,0 +1,556 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.GBase +{ + class GBaseExpression : CommonExpression + { + + public GBaseExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + break; + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"({getExp(operandExp)} not in ('0','F','f'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Char": return $"substring(cast({getExp(operandExp)} as varchar(10)) from 1 for 1)"; + case "System.DateTime": return $"to_date({getExp(operandExp)})"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(18,6))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(18,10))"; + case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Int32": return $"cast({getExp(operandExp)} as integer)"; + case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.SByte": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": return $"cast({getExp(operandExp)} as varchar(8000))"; + case "System.UInt16": return $"cast({getExp(operandExp)} as integer)"; + case "System.UInt32": return $"cast({getExp(operandExp)} as bigint)"; + case "System.UInt64": return $"cast({getExp(operandExp)} as decimal(21,0))"; + case "System.Guid": return $"substring(cast({getExp(operandExp)} as char(36)) from 1 for 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','F','f'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as varchar(10)) from 1 for 1)"; + case "System.DateTime": return $"to_date({getExp(callExp.Arguments[0])})"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,6))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,10))"; + case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as integer)"; + case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.String": return $"cast({getExp(callExp.Arguments[0])} as varchar(8000))"; + case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as integer)"; + case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,0))"; + case "System.Guid": return $"substring(cast({getExp(callExp.Arguments[0])} as char(36)) from 1 for 36)"; + } + return null; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "cast(random() as float)"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as varchar(8000))" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + if (argIndex >= callExp.Arguments.Count) break; + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + var left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + if (a % 500 == 499) arrSb.Append(" \r\n \r\n"); //500元素分割, 3空格\r\n4空格 + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "current_date"; + case "MinValue": return "to_date('0001-1-1', 'YYYY-MM-DD')"; + case "MaxValue": return "to_date('9999-12-31 23:59:59', 'YYYY-MM-DD HH24:MI:SS')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"to_date(to_char({left}, 'YYYY-MM-DD'), 'YYYY-MM-DD')"; + case "TimeOfDay": return $"('0 '||to_char({left}, 'HH24:MI:SS.FF3'))::interval day(9) to fraction"; + case "DayOfWeek": return $"weekday({left})"; + case "Day": return $"day({left})"; + case "DayOfYear": return $"cast(to_char({left},'DDD') as int)"; + case "Month": return $"month({left})"; + case "Year": return $"year({left})"; + case "Hour": return $"cast(to_char({left},'HH24') as int)"; + case "Minute": return $"cast(to_char({left},'MI') as int)"; + case "Second": return $"cast(to_char({left},'SS') as int)"; + case "Millisecond": return $"cast(to_char({left},'FF3') as int)"; + //case "Ticks": return $"cast(to_char({left},'FF7') as bigint)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "interval(0) day(9) to fraction"; //秒 Ticks / 1000,000,0 + case "MaxValue": return "interval(99 23:59:59.999) day(9) to fraction"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"({left})::interval day(9) to day::varchar(40)::int8"; + case "Hours": return $"substr(substring_index(({left})::varchar(40),' ',-1),1,2)::int8"; + case "Milliseconds": return $"substring_index(({left})::varchar(40),'.',-1)::int8"; + case "Minutes": return $"substr(substring_index(({left})::varchar(40),' ',-1),4,2)::int8"; + case "Seconds": return $"substr(substring_index(({left})::varchar(40),' ',-1),7,2)::int8"; + case "Ticks": return $"(({left})::interval day(9) to day::varchar(40)::int8 *24*60*60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),1,2)::int8 *60*60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),4,2)::int8 *60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),7,2)::int8 *1000 + substring_index(({left})::varchar(40),'.',-1)::int8) * 10000"; + case "TotalDays": return $"(({left})::interval day(9) to day::varchar(40)::int8 *24 + substr(substring_index(({left})::varchar(40),' ',-1),1,2)::int8) /24.0"; + case "TotalHours": return $"(({left})::interval day(9) to day::varchar(40)::int8 *24*60 + substr(substring_index(({left})::varchar(40),' ',-1),1,2)::int8 *60 + substr(substring_index(({left})::varchar(40),' ',-1),4,2)::int8) /60.0"; + case "TotalMilliseconds": return $"(({left})::interval day(9) to day::varchar(40)::int8 *24*60*60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),1,2)::int8 *60*60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),4,2)::int8 *60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),7,2)::int8 *1000 + substring_index(({left})::varchar(40),'.',-1)::int8)"; + case "TotalMinutes": return $"(({left})::interval day(9) to day::varchar(40)::int8 *24*60*60 + substr(substring_index(({left})::varchar(40),' ',-1),1,2)::int8 *60*60 + substr(substring_index(({left})::varchar(40),' ',-1),4,2)::int8 *60 + substr(substring_index(({left})::varchar(40),' ',-1),7,2)::int8) /60.0"; + case "TotalSeconds": return $"(({left})::interval day(9) to day::varchar(40)::int8 *24*60*60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),1,2)::int8 *60*60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),4,2)::int8 *60*1000 + substr(substring_index(({left})::varchar(40),' ',-1),7,2)::int8 *1000 + substring_index(({left})::varchar(40),'.',-1)::int8) /1000.0"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or trim({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 expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinGBaseWmConcatText"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"({args0Value})||'%'")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"'%'||({args0Value})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'||cast({args0Value} as varchar(8000))||'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substring({left} from {substrArgs1})"; + return $"substring({left} from {substrArgs1} for {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(instr({indexOfFindStr}, {left}, {locateArgs1})-1)"; + } + return $"(instr({indexOfFindStr}, {left})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"trim(leading from {left})"; + if (exp.Method.Name == "TrimEnd") return $"trim(trailing from {left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceil({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"cast(to_char(last_day(to_date(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01','yyyy-mm-dd')),'DD') as int)"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0"; + + case "Parse": return $"to_date({getExp(exp.Arguments[0])})"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"to_date({getExp(exp.Arguments[0])})"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left} + ({args1}))"; + case "AddDays": return $"({left} + ({args1}) units day)"; + case "AddHours": return $"({left} + ({args1}) units hour)"; + case "AddMilliseconds": return $"({left} + ({args1})/1000 units fraction)"; + case "AddMinutes": return $"({left} + ({args1}) units minute)"; + case "AddMonths": return $"({left} + ({args1}) units month)"; + case "AddSeconds": return $"({left} + ({args1}) units second)"; + case "AddTicks": return $"({left} + ({args1})/10000000 units fraction)"; + case "AddYears": return $"({left} + ({args1}) units year)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"({left} - {args1})"; + case "System.TimeSpan": return $"({left} - {args1})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left} - {args1})"; + case "ToString": + var defaultFmt = "'YYYY-MM-DD HH24:MI:SS'"; + if (left.StartsWith("'") || left.EndsWith("'")) + { + var precision = left.LastIndexOf('.'); + if (precision != -1) + { + precision = left.Substring(precision).Length - 2; + if (precision > 0) defaultFmt = $"'YYYY-MM-DD HH24:MI:SS.FF{precision}'"; + } + left = $"to_date({left},{defaultFmt})"; + } + if (exp.Arguments.Count == 0) return $"to_char({left},{defaultFmt})"; + 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 argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(interval(0) day(9) to fraction + ({getExp(exp.Arguments[0])}) units day)"; + case "FromHours": return $"(interval(0) day(9) to fraction + ({getExp(exp.Arguments[0])}) units hour)"; + case "FromMilliseconds": return $"(interval(0) day(9) to fraction + ({getExp(exp.Arguments[0])})/1000 units fraction)"; + case "FromMinutes": return $"(interval(0) day(9) to fraction + ({getExp(exp.Arguments[0])}) units minute)"; + case "FromSeconds": return $"(interval(0) day(9) to fraction + ({getExp(exp.Arguments[0])}) units second)"; + case "FromTicks": return $"(interval(0) day(9) to fraction + ({getExp(exp.Arguments[0])})/10000000 units fraction)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to fraction)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to fraction)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left} + {args1})"; + case "Subtract": return $"({left} - ({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left} - ({args1}))"; + case "ToString": return $"cast({left} as varchar(50))"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as varchar(10)) from 1 for 1)"; + case "ToDateTime": return $"to_date({getExp(exp.Arguments[0])})"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(18,6))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(18,10))"; + case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToInt32": return $"cast({getExp(exp.Arguments[0])} as integer)"; + case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": return $"cast({getExp(exp.Arguments[0])} as varchar(8000))"; + case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as integer)"; + case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as decimal(18,0))"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.GBase/GBaseExtensions.cs b/Providers/FreeSql.Provider.GBase/GBaseExtensions.cs new file mode 100644 index 00000000..0b91729e --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseExtensions.cs @@ -0,0 +1,15 @@ +using FreeSql; +using FreeSql.GBase.Curd; +using System; + +public static partial class FreeSqlGBaseGlobalExtensions +{ + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatGBase(this string that, params object[] args) => _gbaseAdo.Addslashes(that, args); + static FreeSql.GBase.GBaseAdo _gbaseAdo = new FreeSql.GBase.GBaseAdo(); +} diff --git a/Providers/FreeSql.Provider.GBase/GBaseProvider.cs b/Providers/FreeSql.Provider.GBase/GBaseProvider.cs new file mode 100644 index 00000000..e2feb933 --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseProvider.cs @@ -0,0 +1,150 @@ +using FreeSql.GBase.Curd; +using FreeSql.Internal.CommonProvider; +using System; +using System.Data; +using System.Data.Common; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; + +namespace FreeSql.GBase +{ + + public class GBaseProvider : BaseDbProvider, IFreeSql + { + public override ISelect CreateSelectProvider(object dywhere) => new GBaseSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new GBaseInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new GBaseUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new GBaseDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new GBaseInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public GBaseProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new GBaseUtils(this); + this.InternalCommonExpression = new GBaseExpression(this.InternalCommonUtils); + + this.Ado = new GBaseAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new GBaseDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new GBaseCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + this.Aop.CommandBefore += (_, e) => + { + if (e.Command.CommandType == CommandType.StoredProcedure) + { + if (e.Command.CommandText.Trim().StartsWith("{call ", StringComparison.OrdinalIgnoreCase) == false) + { + var args = string.Join(", ", Enumerable.Range(0, e.Command.Parameters.Count) + .Select(a => "?")); + var cmdText = $"{{call {e.Command.CommandText}({args})}}"; + + foreach (DbParameter parameter in e.Command.Parameters) + { + if (parameter.DbType == DbType.String && parameter.Size <= 0) + parameter.Size = 255; + } + e.Command.CommandText = cmdText; + } + } + }; + + this.Aop.AuditDataReader += (_, e) => + { + var dbtype = e.DataReader.GetDataTypeName(e.Index); + switch (dbtype) + { + case "CHAR": + case "VARCHAR": + case "BOOLEAN": + case "SMALLINT": + case "INTEGER": + case "DECIMAL": + case "FLOAT": + case "SMALLFLOAT": + return; + case "BIGINT": + //Unkonw SQL type -- 114. + try + { + e.Value = e.DataReader.GetInt64(e.Index); + return; + } + catch + { + e.Value = e.DataReader.GetValue(e.Index); + if (e.Value == DBNull.Value) e.Value = null; + return; + } + case "BLOB": + //Unkonw SQL type -- 102. + Stream stm = null; + try + { + stm = e.DataReader.GetStream(e.Index); + } + catch + { + e.Value = e.DataReader.GetValue(e.Index); + if (e.Value == DBNull.Value) e.Value = null; + return; + } + + using (var ms = new MemoryStream()) + { + var stmbuf = new byte[1]; + while (true) + { + if (stm.Read(stmbuf, 0, 1) <= 0) break; + ms.Write(stmbuf, 0, 1); + } + e.Value = ms.ToArray(); + ms.Close(); + } + return; + } + if (dbtype.StartsWith("INTERVAL DAY")) + { + //INTERVAL DAY(3) TO FRACTION(3) + //异常:Unknown SQL type - 110. + var tsv = ""; + try + { + tsv = e.DataReader.GetString(e.Index)?.Trim().Replace(' ', ':'); + } + catch + { + e.Value = e.DataReader.GetValue(e.Index); + if (e.Value == DBNull.Value) e.Value = null; + return; + } + e.Value = TimeSpan.Parse(tsv); + return; + } + }; + } + + ~GBaseProvider() => this.Dispose(); + int _disposeCounter; + public override void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} + + +//--== GBase 8s Information for this install ==-- +//$GBASEDBTSERVER : gbase01 +//$GBASEDBTDIR : /opt/gbase +//USER HOME : /home/gbase +//DBSPACE DIR : /data/gbase +//IP ADDRESS : 192.168.164.134 127.0.0.1 +//PORT NUMBER : 9088 +//$DB_LOCALE : zh_CN.utf8 +//$CLIENT_LOCALE : zh_CN.utf8 +//JDBC URL : jdbc:gbasedbt-sqli://IPADDR:9088/testdb:GBASEDBTSERVER=gbase01;DB_LOCALE=zh_CN.utf8;CLIENT_LOCALE=zh_CN.utf8;IFX_LOCK_MODE_WAIT=10 +//JDBC USERNAME : gbasedbt +//JDBC PASSWORD : GBase123 \ No newline at end of file diff --git a/Providers/FreeSql.Provider.GBase/GBaseUtils.cs b/Providers/FreeSql.Provider.GBase/GBaseUtils.cs new file mode 100644 index 00000000..e477be5f --- /dev/null +++ b/Providers/FreeSql.Provider.GBase/GBaseUtils.cs @@ -0,0 +1,118 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Globalization; + +namespace FreeSql.GBase +{ + + class GBaseUtils : CommonUtils + { + public GBaseUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = "?"; + var ret = new OdbcParameter { ParameterName = "?", Value = value }; + var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (col != null) + { + var dbtype2 = (OdbcType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize }); + switch (dbtype2) + { + case OdbcType.VarBinary: + break; + default: + dbtype = dbtype2; + //if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; + } + } + ret.OdbcType = dbtype; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject("*", obj, "?", (name, type, value) => + { + var ret = new OdbcParameter { ParameterName = $"{name}" }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + else + { + ret.OdbcType = OdbcType.VarChar; + ret.Size = 8000; + } + ret.Value = value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatGBase(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return nametrim; + } + return string.Join(":", name); + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return nametrim; + } + public override string[] SplitTableName(string name) => name?.Split(new char[] { ':' }, 1); + public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left},{right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left}/{right})"; + public override string Now => "current"; + public override string NowUtc => "current"; + + public override string QuoteWriteParamterAdapter(Type type, string paramterName) => paramterName; + protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + if (type == typeof(byte[])) + { + var pam = AppendParamter(specialParams, "", null, type, value); + return pam.ParameterName; + } + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + return $"interval({ts.Days} {ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}) day(9) to fraction"; + } + if (type == typeof(DateTime) || type == typeof(DateTime?)) + { + if (col?.DbPrecision > 0) + return string.Concat("'", ((DateTime)value).ToString($"yyyy-MM-dd HH:mm:ss.{"f".PadRight(col.DbPrecision, 'f')}"), "'"); + return string.Concat("'", ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"), "'"); + } + if (type == typeof(string) && ((string)value)?.Length > 8000) + { + var pam = AppendParamter(specialParams, "", null, type, value); + ((OdbcParameter)pam).OdbcType = OdbcType.Text; + return pam.ParameterName; + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.GBase/key.snk b/Providers/FreeSql.Provider.GBase/key.snk new file mode 100644 index 00000000..be114935 Binary files /dev/null and b/Providers/FreeSql.Provider.GBase/key.snk differ diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 11c8e10e..b75109f4 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs index bf079acd..a4968d86 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs @@ -306,7 +306,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index db2c1d91..c0bbedee 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 371e2cc5..fd322fd8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 2591ac38..5cc547c3 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -314,7 +314,7 @@ where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseI DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6a3111cc..3842da1a 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;netstandard2.1;netcoreapp2.1;netcoreapp3.1; - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs index 3a43ed35..2c4f3bd7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -50,10 +50,11 @@ public static class FreeSqlMySqlConnectorGlobalExtensions { if (insert.InternalConnection == null && insert.InternalTransaction == null) { - using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) - { - writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection)); - } + if (insert._orm.Ado?.TransactionCurrentThread != null) + writeToServer(new MySqlBulkCopy(insert._orm.Ado.TransactionCurrentThread.Connection as MySqlConnection, insert._orm.Ado?.TransactionCurrentThread as MySqlTransaction)); + else + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection)); } else if (insert.InternalTransaction != null) { @@ -109,10 +110,11 @@ public static class FreeSqlMySqlConnectorGlobalExtensions { if (insert.InternalConnection == null && insert.InternalTransaction == null) { - using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) - { - await writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection)); - } + if (insert._orm.Ado?.TransactionCurrentThread != null) + await writeToServer(new MySqlBulkCopy(insert._orm.Ado.TransactionCurrentThread.Connection as MySqlConnection, insert._orm.Ado?.TransactionCurrentThread as MySqlTransaction)); + else + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + await writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection)); } else if (insert.InternalTransaction != null) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 844a5b0a..ca9e5eff 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -406,7 +406,7 @@ where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 9ff98b3a..4f286b8c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs index 006d7f34..b8b29c0f 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs @@ -307,7 +307,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index e3996d91..c1e9254f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -280,7 +280,7 @@ where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseI DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index c77317cf..7d78ee67 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -379,7 +379,7 @@ where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index ef6fc7bf..56ed17ae 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -322,7 +322,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index 7c95ad8e..df5cfbba 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -329,7 +329,7 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), " DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ac62f4de..b994a34b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index e44f30f4..ecd21de4 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -379,7 +379,7 @@ where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs index dff0b1c9..2a216ce4 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs @@ -48,15 +48,19 @@ public static partial class FreeSqlOracleGlobalExtensions { if (insert.InternalConnection == null && insert.InternalTransaction == null) { - using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) - { - using (var bulkCopy = copyOptions == OracleBulkCopyOptions.Default ? - new OracleBulkCopy(conn.Value as OracleConnection) : - new OracleBulkCopy(conn.Value as OracleConnection, copyOptions)) - { + if (insert._orm.Ado?.TransactionCurrentThread != null) + using (var bulkCopy = new OracleBulkCopy(insert._orm.Ado.TransactionCurrentThread.Connection as OracleConnection, copyOptions)) writeToServer(bulkCopy); + else + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + using (var bulkCopy = copyOptions == OracleBulkCopyOptions.Default ? + new OracleBulkCopy(conn.Value as OracleConnection) : + new OracleBulkCopy(conn.Value as OracleConnection, copyOptions)) + { + writeToServer(bulkCopy); + } } - } } else if (insert.InternalTransaction != null) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d0dd6bac..05c8e43b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 96ebf9bb..64e06c47 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -432,7 +432,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index ff07cb6c..09d595eb 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs index 0f9ce722..f26e9592 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs @@ -325,7 +325,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 10df19c0..23e0595f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 828214f4..2f501014 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -332,7 +332,7 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), " DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = ++position }); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index b96e4b42..afca4c55 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -92,15 +92,19 @@ public static partial class FreeSqlSqlServerGlobalExtensions { if (insert.InternalConnection == null && insert.InternalTransaction == null) { - using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) - { - using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? - new SqlBulkCopy(conn.Value as SqlConnection) : - new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) - { + if (insert._orm.Ado?.TransactionCurrentThread != null) + using (var bulkCopy = new SqlBulkCopy(insert._orm.Ado.TransactionCurrentThread.Connection as SqlConnection, copyOptions, insert._orm.Ado.TransactionCurrentThread as SqlTransaction)) writeToServer(bulkCopy); + else + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(conn.Value as SqlConnection) : + new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) + { + writeToServer(bulkCopy); + } } - } } else if (insert.InternalTransaction != null) { @@ -167,15 +171,19 @@ public static partial class FreeSqlSqlServerGlobalExtensions { if (insert.InternalConnection == null && insert.InternalTransaction == null) { - using (var conn = await insert.InternalOrm.Ado.MasterPool.GetAsync()) - { - using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? - new SqlBulkCopy(conn.Value as SqlConnection) : - new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) - { + if (insert._orm.Ado?.TransactionCurrentThread != null) + using (var bulkCopy = new SqlBulkCopy(insert._orm.Ado.TransactionCurrentThread.Connection as SqlConnection, copyOptions, insert._orm.Ado.TransactionCurrentThread as SqlTransaction)) await writeToServerAsync(bulkCopy); + else + using (var conn = await insert.InternalOrm.Ado.MasterPool.GetAsync()) + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(conn.Value as SqlConnection) : + new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) + { + await writeToServerAsync(bulkCopy); + } } - } } else if (insert.InternalTransaction != null) { diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 9ea9840a..c5d8ab6c 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net60;net50;net451;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c0ab502c..69ebc1e6 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.6.100 + 3.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs index 2faf4291..c1b5eb56 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs @@ -204,7 +204,7 @@ namespace FreeSql.Sqlite DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment, + Comment = comment, DefaultValue = defaultValue, Position = position }); diff --git a/README.md b/README.md index 151bba49..608dbe2c 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ FreeSql is a powerful O/RM component, supports .NET Core 2.1+, .NET Framework 4. - 🌲 Support expression functions, and customizable analysis. - 🏁 Support one-to-many and many-to-many navigation properties, include and lazy loading. - 📃 Support Read/Write separation, Splitting Table/Database, Global filters, Optimistic and pessimistic locker. -- 🌳 Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/MsAccess, etc. +- 🌳 Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/ClickHouse/MsAccess, etc. QQ Groups:4336577(full)、8578575(full)、**52508226(available)** diff --git a/README.zh-CN.md b/README.zh-CN.md index df179657..3775865d 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -20,7 +20,7 @@ FreeSql 是一款功能强大的对象关系映射(O/RM)组件,支持 .NET - ✒ 支持 丰富的表达式函数,以及灵活的自定义解析; - 🏁 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - 📃 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; -- 🌳 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/Access 等数据库; +- 🌳 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/ClickHouse/Access 等数据库; QQ群:4336577(已满)、8578575(已满)、52508226(在线)