From 3193aa79d55d1fcece900e54b21d747b502b0d2e Mon Sep 17 00:00:00 2001
From: 2881099 <2881099@qq.com>
Date: Tue, 23 Aug 2022 04:13:49 +0800
Subject: [PATCH] v3.2.666-preview20220824
---
Directory.Build.props | 2 +-
.../FreeSql.Extensions.BaseEntity.csproj | 2 +-
.../FreeSql.Extensions.JsonMap.csproj | 2 +-
.../FreeSql.Extensions.LazyLoading.csproj | 2 +-
.../FreeSql.Extensions.Linq.csproj | 2 +-
.../FreeSql.Generator.csproj | 2 +-
FreeSql.All/FreeSql.All.csproj | 2 +-
FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +-
FreeSql.DbContext/FreeSql.DbContext.xml | 9 -
FreeSql.Repository/FreeSql.Repository.csproj | 2 +-
.../MySqlConnector/Curd/MySqlSelectTest.cs | 2 +-
.../MySql/Curd/MySqlSelectTest.cs | 2 +-
.../FreeSql.Tests.Provider.OracleOledb.csproj | 29 +
.../OracleOledb/Curd/OracleOledbDeleteTest.cs | 105 +
...ledbInsertOrUpdateIfExistsDoNothingTest.cs | 425 ++++
.../Curd/OracleOledbInsertOrUpdateTest.cs | 467 ++++
.../OracleOledb/Curd/OracleOledbInsertTest.cs | 341 +++
.../OracleOledb/Curd/OracleOledbSelectTest.cs | 1995 +++++++++++++++++
.../OracleOledb/Curd/OracleOledbUpdateTest.cs | 194 ++
.../OracleOledb/MapType/BoolNullableTest.cs | 1571 +++++++++++++
.../OracleOledb/MapType/BoolTest.cs | 1105 +++++++++
.../OracleOledb/MapType/DateTimeOffSetTest.cs | 54 +
.../OracleOledb/MapType/EnumTest.cs | 261 +++
.../OracleOledb/MapType/ToStringTest.cs | 570 +++++
.../OracleOledbAdo/OracleAdoTest.cs | 75 +
.../OracleOledb/OracleOledbAopTest.cs | 40 +
.../OracleOledb/OracleOledbCodeFirstTest.cs | 603 +++++
.../OracleOledb/OracleOledbDbFirstTest.cs | 67 +
.../OracleOledbExpression/ConvertTest.cs | 169 ++
.../OracleOledbExpression/DateTimeTest.cs | 732 ++++++
.../OracleOledbExpression/MathTest.cs | 156 ++
.../OracleOledbExpression/OtherTest.cs | 165 ++
.../OracleOledbExpression/StringTest.cs | 827 +++++++
.../OracleOledbExpression/TimeSpanTest.cs | 293 +++
.../FreeSql.Tests.Provider.OracleOledb/g.cs | 26 +
.../MySql/Curd/MySqlSelectTest.cs | 2 +-
FreeSql.sln | 33 +-
FreeSql/FreeSql.csproj | 2 +-
FreeSql/FreeSql.xml | 5 -
.../FreeSql.Provider.ClickHouse.csproj | 2 +-
.../FreeSql.Provider.Custom.csproj | 2 +-
.../FreeSql.Provider.Dameng.csproj | 2 +-
.../FreeSql.Provider.Firebird.csproj | 2 +-
.../FreeSql.Provider.GBase.csproj | 2 +-
.../FreeSql.Provider.KingbaseES.csproj | 2 +-
.../FreeSql.Provider.MsAccess.csproj | 2 +-
.../FreeSql.Provider.MySql.csproj | 2 +-
.../FreeSql.Provider.MySqlConnector.csproj | 2 +-
.../FreeSql.Provider.Odbc.csproj | 2 +-
.../FreeSql.Provider.Oracle.csproj | 2 +-
.../OracleAdo/OracleAdo.cs | 2 +-
.../OracleCodeFirst.cs | 10 +-
.../FreeSql.Provider.Oracle/OracleDbFirst.cs | 14 +-
.../FreeSql.Provider.Oracle/OracleProvider.cs | 27 +
.../FreeSql.Provider.OracleOledb.csproj | 2 +-
.../OracleOledbUtils.cs | 10 +
.../FreeSql.Provider.PostgreSQL.csproj | 2 +-
.../FreeSql.Provider.ShenTong.csproj | 2 +-
.../FreeSql.Provider.SqlServer.csproj | 2 +-
...FreeSql.Provider.SqlServerForSystem.csproj | 2 +-
.../FreeSql.Provider.Sqlite.csproj | 2 +-
.../FreeSql.Provider.SqliteCore.csproj | 2 +-
62 files changed, 10382 insertions(+), 60 deletions(-)
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/FreeSql.Tests.Provider.OracleOledb.csproj
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbDeleteTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateIfExistsDoNothingTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbSelectTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbUpdateTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/MapType/BoolNullableTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/MapType/BoolTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/MapType/DateTimeOffSetTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/MapType/EnumTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/MapType/ToStringTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbAdo/OracleAdoTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbAopTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbCodeFirstTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbDbFirstTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbExpression/ConvertTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbExpression/DateTimeTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbExpression/MathTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbExpression/OtherTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbExpression/StringTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/OracleOledbExpression/TimeSpanTest.cs
create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/g.cs
diff --git a/Directory.Build.props b/Directory.Build.props
index eb0b7ff8..af94e553 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -11,7 +11,7 @@
diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj
index 476b7a51..5ecc02fc 100644
--- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj
+++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj
@@ -19,7 +19,7 @@
key.snk
false
latest
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj
index 90c05b35..0aadb958 100644
--- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj
+++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj
@@ -18,7 +18,7 @@
true
key.snk
false
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj
index 2b49a6e1..3fd2b86b 100644
--- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj
+++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj
@@ -15,7 +15,7 @@
$(AssemblyName)
true
true
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj
index 3814e5b2..3886976f 100644
--- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj
+++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj
@@ -18,7 +18,7 @@
true
key.snk
false
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj
index 10f48d64..03182a5c 100644
--- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj
+++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj
@@ -13,7 +13,7 @@
https://github.com/2881099/FreeSql
https://github.com/2881099/FreeSql
FreeSql DbFirst 实体生成器
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj
index 43f7676a..5622b597 100644
--- a/FreeSql.All/FreeSql.All.csproj
+++ b/FreeSql.All/FreeSql.All.csproj
@@ -17,7 +17,7 @@
true
key.snk
false
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj
index 27d5e097..be7153b4 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.csproj
+++ b/FreeSql.DbContext/FreeSql.DbContext.csproj
@@ -17,7 +17,7 @@
true
key.snk
false
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index 26522f10..537315e2 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -800,14 +800,5 @@
-
-
- 批量注入 Repository,可以参考代码自行调整
-
-
-
-
-
-
diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj
index 45ccb644..f842a8ff 100644
--- a/FreeSql.Repository/FreeSql.Repository.csproj
+++ b/FreeSql.Repository/FreeSql.Repository.csproj
@@ -17,7 +17,7 @@
true
key.snk
false
- 3.2.666-preview20220823
+ 3.2.666-preview20220824
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs
index 3e1729cc..fc8c755c 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs
@@ -1292,7 +1292,7 @@ FROM ( SELECT max(a.`Id`) `TaskId`, max(a.`Type`) `TaskType`, a.`ProcessId`, a.`
WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3'))
GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a
LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId`
-WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12);
+WHERE ((b.`IsFinished` = 1 OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12);
var grouplist12 = g.mysql.Select()
.AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null)
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs
index 4dbc3074..e5d06458 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs
@@ -1172,7 +1172,7 @@ FROM ( SELECT max(a.`Id`) `TaskId`, max(a.`Type`) `TaskType`, a.`ProcessId`, a.`
WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3'))
GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a
LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId`
-WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12);
+WHERE ((b.`IsFinished` = 1 OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12);
var grouplist12 = g.mysql.Select()
.AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null)
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/FreeSql.Tests.Provider.OracleOledb.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/FreeSql.Tests.Provider.OracleOledb.csproj
new file mode 100644
index 00000000..be27765b
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/FreeSql.Tests.Provider.OracleOledb.csproj
@@ -0,0 +1,29 @@
+
+
+
+ net6.0;netcoreapp3.1;
+ false
+
+
+
+ 3
+ 1701;1702;1591
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbDeleteTest.cs
new file mode 100644
index 00000000..a98f96de
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbDeleteTest.cs
@@ -0,0 +1,105 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.OracleOledb
+{
+ public class OracleOledbDeleteTest
+ {
+
+ IDelete delete => g.oracle.Delete(); //��������
+
+ [Table(Name = "tb_topic22211")]
+ 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.oracle.Delete().ToSql());
+ var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql();
+ Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql);
+
+ sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql();
+ Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql);
+
+ sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql();
+ Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql);
+
+ sql = g.oracle.Delete(new { id = 1 }).ToSql();
+ Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql);
+
+ sql = g.oracle.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_TOPIC22211\" WHERE (\"ID\" = 1)", sql);
+
+ sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", "");
+ Assert.Equal("DELETE FROM \"TB_TOPIC22211\" 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_TOPIC22211\" 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_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
+ }
+ [Fact]
+ public void ExecuteAffrows()
+ {
+
+ var id = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity();
+ Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows());
+ }
+ [Fact]
+ public void ExecuteDeleted()
+ {
+
+ //var item = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted();
+ //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id);
+ }
+
+ [Fact]
+ public void AsTable()
+ {
+ Assert.Null(g.oracle.Delete().ToSql());
+ var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql();
+ Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql);
+
+ sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql();
+ Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql);
+
+ sql = g.oracle.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.oracle.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.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateIfExistsDoNothingTest.cs
new file mode 100644
index 00000000..1cd401af
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateIfExistsDoNothingTest.cs
@@ -0,0 +1,425 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.OracleOledb
+{
+ public class OracleOledbInsertOrUpdateIfExistsDoNothingTest
+ {
+ IFreeSql fsql => g.oracle;
+
+ [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(1, 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(4, 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(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().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 ALL
+INTO ""TBIOUDB022""(""NAME"") VALUES('01')
+INTO ""TBIOUDB022""(""NAME"") VALUES('02')
+INTO ""TBIOUDB022""(""NAME"") VALUES('03')
+INTO ""TBIOUDB022""(""NAME"") VALUES('04')
+ SELECT 1 FROM DUAL", 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 ALL
+INTO ""TBIOUDB022""(""NAME"") VALUES('001')
+INTO ""TBIOUDB022""(""NAME"") VALUES('002')
+INTO ""TBIOUDB022""(""NAME"") VALUES('003')
+INTO ""TBIOUDB022""(""NAME"") VALUES('004')
+ SELECT 1 FROM DUAL", 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 ALL
+INTO ""TBIOUDB022""(""NAME"") VALUES('00001')
+INTO ""TBIOUDB022""(""NAME"") VALUES('00002')
+INTO ""TBIOUDB022""(""NAME"") VALUES('00003')
+INTO ""TBIOUDB022""(""NAME"") VALUES('00004')
+ SELECT 1 FROM DUAL", 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 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"", systimestamp 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"", systimestamp 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"", systimestamp 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"", systimestamp as ""CREATETIME"" FROM dual
+UNION ALL
+ SELECT 2, '02', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 3, '03', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 4, '04', 0, systimestamp 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"", systimestamp as ""CREATETIME"" FROM dual
+UNION ALL
+ SELECT 2, '002', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 3, '003', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 4, '004', 0, systimestamp 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.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateTest.cs
new file mode 100644
index 00000000..0b9bda64
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertOrUpdateTest.cs
@@ -0,0 +1,467 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.OracleOledb
+{
+ public class OracleOledbInsertOrUpdateTest
+ {
+ IFreeSql fsql => g.oracle;
+
+ [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 ""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 ""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 ""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 ""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 ""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 ""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 ""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 ""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 ""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 ""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 ALL
+INTO ""TBIOU022""(""NAME"") VALUES('01')
+INTO ""TBIOU022""(""NAME"") VALUES('02')
+INTO ""TBIOU022""(""NAME"") VALUES('03')
+INTO ""TBIOU022""(""NAME"") VALUES('04')
+ SELECT 1 FROM DUAL", 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 ALL
+INTO ""TBIOU022""(""NAME"") VALUES('001')
+INTO ""TBIOU022""(""NAME"") VALUES('002')
+INTO ""TBIOU022""(""NAME"") VALUES('003')
+INTO ""TBIOU022""(""NAME"") VALUES('004')
+ SELECT 1 FROM DUAL", 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 ""NAME"" = t2.""NAME""
+WHEN NOT MATCHED THEN
+ insert (""ID"", ""NAME"")
+ values (t2.""ID"", t2.""NAME"")
+
+;
+
+INSERT ALL
+INTO ""TBIOU022""(""NAME"") VALUES('00001')
+INTO ""TBIOU022""(""NAME"") VALUES('00002')
+INTO ""TBIOU022""(""NAME"") VALUES('00003')
+INTO ""TBIOU022""(""NAME"") VALUES('00004')
+ SELECT 1 FROM DUAL", 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 ""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 ""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 ""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 ""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 ""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"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"")
+WHEN MATCHED THEN
+ update set ""NAME"" = t2.""NAME"", ""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"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"")
+WHEN MATCHED THEN
+ update set ""NAME"" = t2.""NAME"", ""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"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"")
+WHEN MATCHED THEN
+ update set ""NAME"" = t2.""NAME"", ""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"", systimestamp as ""CREATETIME"" FROM dual
+UNION ALL
+ SELECT 2, '02', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 3, '03', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.""ID"")
+WHEN MATCHED THEN
+ update set ""NAME"" = t2.""NAME"", ""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"", systimestamp as ""CREATETIME"" FROM dual
+UNION ALL
+ SELECT 2, '002', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 3, '003', 0, systimestamp FROM dual
+UNION ALL
+ SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.""ID"")
+WHEN MATCHED THEN
+ update set ""NAME"" = t2.""NAME"", ""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.OracleOledb/OracleOledb/Curd/OracleOledbInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertTest.cs
new file mode 100644
index 00000000..27c64ea2
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.OracleOledb/OracleOledb/Curd/OracleOledbInsertTest.cs
@@ -0,0 +1,341 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.OracleOledb
+{
+ public class OracleOledbInsertTest
+ {
+
+ IInsert insert => g.oracle.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 InsertDictionary()
+ {
+ var fsql = g.oracle;
+ Dictionary dic = new Dictionary();
+ dic.Add("id", 1);
+ dic.Add("name", "xxxx");
+ var diclist = new List>();
+ diclist.Add(dic);
+ diclist.Add(new Dictionary
+ {
+ ["id"] = 2,
+ ["name"] = "yyyy"
+ });
+
+ var sql1 = fsql.InsertDict(dic).AsTable("table1").ToSql();
+ Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_0, :name_0)", sql1);
+ var sql2 = fsql.InsertDict(diclist).AsTable("table1").ToSql();
+ Assert.Equal(@"INSERT ALL
+INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_0, :name_0)
+INTO ""TABLE1""(""ID"", ""NAME"") VALUES(:id_1, :name_1)
+ SELECT 1 FROM DUAL", sql2);
+ var sql3 = fsql.InsertDict(dic).AsTable("table1").NoneParameter().ToSql();
+ Assert.Equal(@"INSERT INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx')", sql3);
+ var sql4 = fsql.InsertDict(diclist).AsTable("table1").NoneParameter().ToSql();
+ Assert.Equal(@"INSERT ALL
+INTO ""TABLE1""(""ID"", ""NAME"") VALUES(1, 'xxxx')
+INTO ""TABLE1""(""ID"", ""NAME"") VALUES(2, 'yyyy')
+ SELECT 1 FROM DUAL", sql4);
+ }
+
+ [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, CreateTime = DateTime.Now });
+
+ var data = new List