From 511d8f909a6e27408b69b1b5e16420f2b2aa551d Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Sat, 23 May 2020 18:17:54 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=E6=9C=AA=E5=8F=91?=
=?UTF-8?q?=E5=B8=83=E7=9A=84=E5=8A=9F=E8=83=BD=20IFreeSql.InsertOrUpdate?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql.DbContext/FreeSql.DbContext.xml | 18 ---
.../Curd/MySqlInsertOrUpdateTest.cs | 87 +++++++++++
.../Dameng/Curd/DamengInsertOrUpdateTest.cs | 143 +++++++++++++++++
.../MySql/Curd/MySqlInsertOrUpdateTest.cs | 87 +++++++++++
.../Oracle/Curd/OracleInsertOrUpdateTest.cs | 144 ++++++++++++++++++
.../Curd/PostgreSQLInsertOrUpdateTest.cs | 87 +++++++++++
.../Curd/SqlServerInsertOrUpdateTest.cs | 141 +++++++++++++++++
.../Dameng/Curd/DamengInsertOrUpdateTest.cs | 144 ++++++++++++++++++
.../MySql/Curd/MySqlInsertOrUpdateTest.cs | 87 +++++++++++
.../Oracle/Curd/OracleInsertOrUpdateTest.cs | 144 ++++++++++++++++++
.../Curd/PostgreSQLInsertOrUpdateTest.cs | 87 +++++++++++
.../Curd/SqlServerInsertOrUpdateTest.cs | 141 +++++++++++++++++
.../Sqlite/Curd/SqliteInsertOrUpdateTest.cs | 76 +++++++++
FreeSql/FreeSql.xml | 8 +
.../CommonProvider/InsertOrUpdateProvider.cs | 134 +++++++++++++++-
.../Curd/DamengInsertOrUpdate.cs | 64 +++++---
.../Curd/MySqlInsertOrUpdate.cs | 39 +++--
.../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 64 +++++---
.../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 37 +++--
.../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 64 +++++---
.../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 48 ++++--
.../Curd/OdbcSqlServerInsertOrUpdate.cs | 67 +++++---
.../Curd/OracleInsertOrUpdate.cs | 64 +++++---
.../Curd/PostgreSQLInsertOrUpdate.cs | 48 ++++--
.../Curd/SqlServerInsertOrUpdate.cs | 67 +++++---
.../Curd/SqliteInsertOrUpdate.cs | 42 +++--
26 files changed, 1948 insertions(+), 184 deletions(-)
diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index 13ddf83b..132d875e 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -125,13 +125,6 @@
清空状态数据
-
-
- 根据 lambda 条件删除数据
-
-
-
-
添加
@@ -488,14 +481,3 @@
-Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
-
- 批量注入 Repository,可以参考代码自行调整
-
-
-
-
-
-
-
-
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs
index 6198c553..91b56e34 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs
@@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE
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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '011')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(2, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(2, '02')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(5, 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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(8, 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`) VALUES('01'), ('02'), ('03'), ('04')", 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`) VALUES('001'), ('002'), ('003'), ('004')", 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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)
+
+;
+
+INSERT INTO `tbiou022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql);
+ Assert.Equal(12, 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()
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs
index e3832aaa..3901c553 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs
@@ -154,6 +154,149 @@ WHEN NOT MATCHED THEN
public int id { get; set; }
public string name { get; set; }
}
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ iou.ExecuteAffrows();
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql);
+ iou.ExecuteAffrows();
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql);
+ 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);
+ 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);
+ 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);
+ 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()
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs
index 3b9fc212..283e8e75 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs
@@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE
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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '011')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(2, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(2, '02')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(8, 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`) VALUES('01'), ('02'), ('03'), ('04')", 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`) VALUES('001'), ('002'), ('003'), ('004')", 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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)
+
+;
+
+INSERT INTO `tbiou022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql);
+ Assert.Equal(12, 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()
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs
index 156bebbf..8ed896b3 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs
@@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN
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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ iou.ExecuteAffrows();
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql);
+ iou.ExecuteAffrows();
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql);
+ 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);
+ 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);
+ 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);
+ 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()
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs
index 90ce4b5b..e539b712 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs
@@ -95,6 +95,93 @@ ON CONFLICT(""id"") DO UPDATE SET
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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""name""", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""name""", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""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"") VALUES('01'), ('02'), ('03'), ('04')", 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"") VALUES('001'), ('002'), ('003'), ('004')", 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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""name""
+
+;
+
+INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", 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()
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs
index 0c00dbb5..90bc5604 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs
@@ -154,6 +154,147 @@ WHEN NOT MATCHED THEN
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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'01' as name ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'011' as name ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 2 as id, N'02' as name ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", 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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'01' as name
+UNION ALL
+ SELECT 2, N'02'
+UNION ALL
+ SELECT 3, N'03'
+UNION ALL
+ SELECT 4, N'04' ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", 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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'001' as name
+UNION ALL
+ SELECT 2, N'002'
+UNION ALL
+ SELECT 3, N'003'
+UNION ALL
+ SELECT 4, N'004' ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", 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(N'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(N'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(N'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]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", 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]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", 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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'100001' as name
+UNION ALL
+ SELECT 2, N'100002'
+UNION ALL
+ SELECT 3, N'100003'
+UNION ALL
+ SELECT 4, N'100004' ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;
+
+;
+
+INSERT INTO [tbiou022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", 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()
diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs
index 54e4c38a..3a4ceb48 100644
--- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs
@@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN
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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ iou.ExecuteAffrows();
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql);
+ iou.ExecuteAffrows();
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql);
+ 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);
+ 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);
+ 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);
+ 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()
diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs
index 3cfe1a62..471920c9 100644
--- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs
@@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE
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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '011')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(2, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(2, '02')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(5, 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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)", sql);
+ Assert.Equal(8, 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`) VALUES('01'), ('02'), ('03'), ('04')", 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`) VALUES('001'), ('002'), ('003'), ('004')", 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(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
+ON DUPLICATE KEY UPDATE
+`name` = VALUES(`name`)
+
+;
+
+INSERT INTO `tbiou022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql);
+ Assert.Equal(12, 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()
diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs
index e645b7fc..d383cea5 100644
--- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs
@@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN
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()
diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs
index 1b1e853b..4049b04d 100644
--- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs
@@ -95,6 +95,93 @@ ON CONFLICT(""id"") DO UPDATE SET
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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""name""", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""name""", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""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"") VALUES('01'), ('02'), ('03'), ('04')", 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"") VALUES('001'), ('002'), ('003'), ('004')", 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(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
+ON CONFLICT(""id"") DO UPDATE SET
+""name"" = EXCLUDED.""name""
+
+;
+
+INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", 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()
diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs
index 7858a27d..dcbb2a3b 100644
--- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs
@@ -156,6 +156,147 @@ WHEN NOT MATCHED THEN
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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'01' as name ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'011' as name ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 2 as id, N'02' as name ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", 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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'01' as name
+UNION ALL
+ SELECT 2, N'02'
+UNION ALL
+ SELECT 3, N'03'
+UNION ALL
+ SELECT 4, N'04' ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", 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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'001' as name
+UNION ALL
+ SELECT 2, N'002'
+UNION ALL
+ SELECT 3, N'003'
+UNION ALL
+ SELECT 4, N'004' ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;", 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(N'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(N'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(N'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]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", 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]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", 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(@"SET IDENTITY_INSERT [tbiou022] ON;
+MERGE INTO [tbiou022] t1
+USING (SELECT 1 as id, N'100001' as name
+UNION ALL
+ SELECT 2, N'100002'
+UNION ALL
+ SELECT 3, N'100003'
+UNION ALL
+ SELECT 4, N'100004' ) 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);;
+SET IDENTITY_INSERT [tbiou022] OFF;
+
+;
+
+INSERT INTO [tbiou022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", 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()
diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs
index 0412c2fa..2e793f17 100644
--- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs
@@ -81,6 +81,82 @@ namespace FreeSql.Tests.Sqlite
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(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01')", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" });
+ sql = iou.ToSql();
+ Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011')", sql);
+ Assert.Equal(1, iou.ExecuteAffrows());
+
+ iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" });
+ sql = iou.ToSql();
+ Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02')", 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(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')", 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(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')", 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"") VALUES('01'), ('02'), ('03'), ('04')", 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"") VALUES('001'), ('002'), ('003'), ('004')", 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(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
+
+;
+
+INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", 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()
{
diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml
index 40b864cc..f4fd5b54 100644
--- a/FreeSql/FreeSql.xml
+++ b/FreeSql/FreeSql.xml
@@ -2994,6 +2994,13 @@
+
+
+ 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert
+
+
+
+
AsType, Ctor, ClearData 三处地方需要重新加载
@@ -3770,6 +3777,7 @@
Oracle: merge into
Sqlite: replace into
Dameng: merge into
+ 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法
diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs
index 42fe4bee..ba76d54d 100644
--- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs
+++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs
@@ -25,6 +25,7 @@ namespace FreeSql.Internal.CommonProvider
protected DbParameter[] _params;
protected DbTransaction _transaction;
protected DbConnection _connection;
+ public ColumnInfo IdentityColumn { get; }
public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
{
@@ -33,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider
_commonExpression = commonExpression;
_table = _commonUtils.GetTableByEntity(typeof(T1));
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure();
+ IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault();
}
protected void ClearData()
@@ -130,11 +132,10 @@ namespace FreeSql.Internal.CommonProvider
return this;
}
- public void WriteSourceSelectUnionAll(StringBuilder sb)
+ public void WriteSourceSelectUnionAll(List source, StringBuilder sb, List dbParams)
{
- var specialParams = new List();
var didx = 0;
- foreach (var d in _source)
+ foreach (var d in source)
{
if (didx > 0) sb.Append(" \r\nUNION ALL\r\n ");
sb.Append("SELECT ");
@@ -147,7 +148,7 @@ namespace FreeSql.Internal.CommonProvider
else
{
object val = col.GetMapValue(d);
- sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val));
+ sb.Append(_commonUtils.GetNoneParamaterSqlValue(dbParams, col.Attribute.MapType, val));
}
if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name);
++colidx2;
@@ -163,11 +164,82 @@ namespace FreeSql.Internal.CommonProvider
}
++didx;
}
- if (specialParams.Any()) _params = specialParams.ToArray();
+ }
+
+ byte _SplitSourceByIdentityValueIsNullFlag = 0; //防止重复计算 SplitSource
+ ///
+ /// 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert
+ ///
+ ///
+ ///
+ public NaviteTuple, List> SplitSourceByIdentityValueIsNull(List source)
+ {
+ if (_SplitSourceByIdentityValueIsNullFlag == 1) return NaviteTuple.Create(source, new List());
+ if (_SplitSourceByIdentityValueIsNullFlag == 2) return NaviteTuple.Create(new List(), source);
+ if (IdentityColumn == null) return NaviteTuple.Create(source, new List());
+ var ret = NaviteTuple.Create(new List(), new List());
+ foreach (var item in source)
+ {
+ if (object.Equals(_orm.GetEntityValueWithPropertyName(_table.Type, item, IdentityColumn.CsName), IdentityColumn.CsType.CreateInstanceGetDefaultValue()))
+ ret.Item2.Add(item); //自增无值的,记录为直接插入
+ else
+ ret.Item1.Add(item);
+ }
+ return ret;
}
public abstract string ToSql();
public int ExecuteAffrows()
+ {
+ var affrows = 0;
+ var ss = SplitSourceByIdentityValueIsNull(_source);
+ try
+ {
+ if (_transaction != null)
+ {
+ _source = ss.Item1;
+ _SplitSourceByIdentityValueIsNullFlag = 1;
+ affrows += this.RawExecuteAffrows();
+ _source = ss.Item2;
+ _SplitSourceByIdentityValueIsNullFlag = 2;
+ affrows += this.RawExecuteAffrows();
+ }
+ else
+ {
+ using (var conn = _orm.Ado.MasterPool.Get())
+ {
+ _transaction = conn.Value.BeginTransaction();
+ var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null);
+ _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore);
+ try
+ {
+ _source = ss.Item1;
+ _SplitSourceByIdentityValueIsNullFlag = 1;
+ affrows += this.RawExecuteAffrows();
+ _source = ss.Item2;
+ _SplitSourceByIdentityValueIsNullFlag = 2;
+ affrows += this.RawExecuteAffrows();
+ _transaction.Commit();
+ _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null));
+ }
+ catch (Exception ex)
+ {
+ _transaction.Rollback();
+ _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex));
+ throw ex;
+ }
+ _transaction = null;
+ }
+ }
+ }
+ finally
+ {
+ _SplitSourceByIdentityValueIsNullFlag = 0;
+ ClearData();
+ }
+ return affrows;
+ }
+ public int RawExecuteAffrows()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return 0;
@@ -193,7 +265,7 @@ namespace FreeSql.Internal.CommonProvider
}
#if net40
#else
- async public Task ExecuteAffrowsAsync()
+ async public Task RawExecuteAffrowsAsync()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return 0;
@@ -217,6 +289,56 @@ namespace FreeSql.Internal.CommonProvider
}
return affrows;
}
+ async public Task ExecuteAffrowsAsync()
+ {
+ var affrows = 0;
+ var ss = SplitSourceByIdentityValueIsNull(_source);
+ try
+ {
+ if (_transaction != null)
+ {
+ _source = ss.Item1;
+ _SplitSourceByIdentityValueIsNullFlag = 1;
+ affrows += await this.RawExecuteAffrowsAsync();
+ _source = ss.Item2;
+ _SplitSourceByIdentityValueIsNullFlag = 2;
+ affrows += await this.RawExecuteAffrowsAsync();
+ }
+ else
+ {
+ using (var conn = await _orm.Ado.MasterPool.GetAsync())
+ {
+ _transaction = conn.Value.BeginTransaction();
+ var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null);
+ _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore);
+ try
+ {
+ _source = ss.Item1;
+ _SplitSourceByIdentityValueIsNullFlag = 1;
+ affrows += await this.RawExecuteAffrowsAsync();
+ _source = ss.Item2;
+ _SplitSourceByIdentityValueIsNullFlag = 2;
+ affrows += await this.RawExecuteAffrowsAsync();
+ _transaction.Commit();
+ _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null));
+ }
+ catch (Exception ex)
+ {
+ _transaction.Rollback();
+ _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex));
+ throw ex;
+ }
+ _transaction = null;
+ }
+ }
+ }
+ finally
+ {
+ _SplitSourceByIdentityValueIsNullFlag = 0;
+ ClearData();
+ }
+ return affrows;
+ }
#endif
}
}
diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs
index 52f2e955..ec7370ad 100644
--- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs
@@ -1,5 +1,7 @@
using FreeSql.Internal;
using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
using System.Text;
@@ -16,28 +18,54 @@ namespace FreeSql.Dameng.Curd
public override string ToSql()
{
if (_source?.Any() != true) return null;
- if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键");
- var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
- .Append("USING (");
- WriteSourceSelectUnionAll(sb);
- sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
+ 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);
- var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
- if (cols.Any())
- sb.Append("WHEN MATCHED THEN \r\n")
- .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
- a.Attribute.IsVersion ?
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
- ))).Append(" \r\n");
+ string getMergeSql(List data)
+ {
+ if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
- cols = _table.Columns.Values;
- 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.{a.Attribute.Name}"))).Append(")");
+ var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING (");
+ WriteSourceSelectUnionAll(data, sb, dbParams);
+ sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
- return sb.ToString();
+ var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
+ if (cols.Any())
+ sb.Append("WHEN MATCHED THEN \r\n")
+ .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
+ a.Attribute.IsVersion ?
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
+ ))).Append(" \r\n");
+
+ cols = _table.Columns.Values;
+ 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.{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.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs
index 6d530b2f..1106945d 100644
--- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs
@@ -1,5 +1,9 @@
using FreeSql.Internal;
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
+using System.Text;
namespace FreeSql.MySql.Curd
{
@@ -15,15 +19,32 @@ namespace FreeSql.MySql.Curd
{
if (_source?.Any() != true) return null;
- var insert = _orm.Insert()
- .AsTable(_tableRule).AsType(_table.Type)
- .WithConnection(_connection)
- .WithTransaction(_transaction)
- .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
- insert._source = _source;
- var sql = new OnDuplicateKeyUpdate(insert).ToSql();
- _params = insert._params;
- return sql;
+ var sqls = new string[2];
+ var dbParams = new List();
+ var ds = SplitSourceByIdentityValueIsNull(_source);
+ if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false);
+ if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true);
+ _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 getInsertSql(List data, bool flagInsert)
+ {
+ var insert = _orm.Insert()
+ .AsTable(_tableRule).AsType(_table.Type)
+ .WithConnection(_connection)
+ .WithTransaction(_transaction)
+ .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
+ insert._source = data;
+
+ string sql = "";
+ if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
+ else sql = new OnDuplicateKeyUpdate(insert.InsertIdentity()).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.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs
index c5826cdc..d36ee50a 100644
--- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs
@@ -1,5 +1,7 @@
using FreeSql.Internal;
using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
using System.Text;
@@ -16,28 +18,54 @@ namespace FreeSql.Odbc.Dameng
public override string ToSql()
{
if (_source?.Any() != true) return null;
- if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键");
- var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
- .Append("USING (");
- WriteSourceSelectUnionAll(sb);
- sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
+ 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);
- var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
- if (cols.Any())
- sb.Append("WHEN MATCHED THEN \r\n")
- .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
- a.Attribute.IsVersion ?
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
- ))).Append(" \r\n");
+ string getMergeSql(List data)
+ {
+ if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
- cols = _table.Columns.Values;
- 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.{a.Attribute.Name}"))).Append(")");
+ var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING (");
+ WriteSourceSelectUnionAll(data, sb, dbParams);
+ sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
- return sb.ToString();
+ var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
+ if (cols.Any())
+ sb.Append("WHEN MATCHED THEN \r\n")
+ .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
+ a.Attribute.IsVersion ?
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
+ ))).Append(" \r\n");
+
+ cols = _table.Columns.Values;
+ 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.{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.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs
index c8908805..86747427 100644
--- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs
@@ -1,4 +1,6 @@
using FreeSql.Internal;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
namespace FreeSql.Odbc.MySql
@@ -15,15 +17,32 @@ namespace FreeSql.Odbc.MySql
{
if (_source?.Any() != true) return null;
- var insert = _orm.Insert()
- .AsTable(_tableRule).AsType(_table.Type)
- .WithConnection(_connection)
- .WithTransaction(_transaction)
- .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
- insert._source = _source;
- var sql = new OdbcMySqlOnDuplicateKeyUpdate(insert).ToSql();
- _params = insert._params;
- return sql;
+ var sqls = new string[2];
+ var dbParams = new List();
+ var ds = SplitSourceByIdentityValueIsNull(_source);
+ if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false);
+ if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true);
+ _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 getInsertSql(List data, bool flagInsert)
+ {
+ var insert = _orm.Insert()
+ .AsTable(_tableRule).AsType(_table.Type)
+ .WithConnection(_connection)
+ .WithTransaction(_transaction)
+ .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
+ insert._source = data;
+
+ string sql = "";
+ if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
+ else sql = new OdbcMySqlOnDuplicateKeyUpdate(insert.InsertIdentity()).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.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs
index 0c151cc3..1a0766a1 100644
--- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs
@@ -1,5 +1,7 @@
using FreeSql.Internal;
using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
using System.Text;
@@ -16,28 +18,54 @@ namespace FreeSql.Odbc.Oracle
public override string ToSql()
{
if (_source?.Any() != true) return null;
- if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键");
- var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
- .Append("USING (");
- WriteSourceSelectUnionAll(sb);
- sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
+ 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);
- var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
- if (cols.Any())
- sb.Append("WHEN MATCHED THEN \r\n")
- .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
- a.Attribute.IsVersion ?
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
- ))).Append(" \r\n");
+ string getMergeSql(List data)
+ {
+ if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
- cols = _table.Columns.Values;
- 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.{a.Attribute.Name}"))).Append(")");
+ var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING (");
+ WriteSourceSelectUnionAll(data, sb, dbParams);
+ sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
- return sb.ToString();
+ var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
+ if (cols.Any())
+ sb.Append("WHEN MATCHED THEN \r\n")
+ .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
+ a.Attribute.IsVersion ?
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
+ ))).Append(" \r\n");
+
+ cols = _table.Columns.Values;
+ 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.{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.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs
index ec291e6b..311e46b2 100644
--- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs
@@ -1,4 +1,6 @@
using FreeSql.Internal;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
namespace FreeSql.Odbc.PostgreSQL
@@ -15,19 +17,39 @@ namespace FreeSql.Odbc.PostgreSQL
{
if (_source?.Any() != true) return null;
- var insert = _orm.Insert()
- .AsTable(_tableRule).AsType(_table.Type)
- .WithConnection(_connection)
- .WithTransaction(_transaction)
- .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
- insert._source = _source;
- var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert);
- ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray());
- if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false)
- ocdu.DoNothing();
- var sql = ocdu.ToSql();
- _params = insert._params;
- return sql;
+ var sqls = new string[2];
+ var dbParams = new List();
+ var ds = SplitSourceByIdentityValueIsNull(_source);
+ if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false);
+ if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true);
+ _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 getInsertSql(List data, bool flagInsert)
+ {
+ var insert = _orm.Insert()
+ .AsTable(_tableRule).AsType(_table.Type)
+ .WithConnection(_connection)
+ .WithTransaction(_transaction)
+ .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
+ insert._source = data;
+
+ string sql = "";
+ if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
+ else
+ {
+ var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert.InsertIdentity());
+ ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray());
+ if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false)
+ ocdu.DoNothing();
+ sql = ocdu.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.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs
index 85f74a23..69b11d78 100644
--- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs
@@ -1,5 +1,7 @@
using FreeSql.Internal;
using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
using System.Text;
@@ -16,28 +18,59 @@ namespace FreeSql.Odbc.SqlServer
public override string ToSql()
{
if (_source?.Any() != true) return null;
- if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键");
- var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
+ 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();
+ if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n");
+ sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
.Append("USING (");
- WriteSourceSelectUnionAll(sb);
- sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
+ WriteSourceSelectUnionAll(data, sb, dbParams);
+ sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
- var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
- if (cols.Any())
- sb.Append("WHEN MATCHED THEN \r\n")
- .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
- a.Attribute.IsVersion ?
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
- ))).Append(" \r\n");
+ var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
+ if (cols.Any())
+ sb.Append("WHEN MATCHED THEN \r\n")
+ .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
+ a.Attribute.IsVersion ?
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
+ ))).Append(" \r\n");
- cols = _table.Columns.Values;
- 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.{a.Attribute.Name}"))).Append(");");
+ cols = _table.Columns.Values;
+ 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.{a.Attribute.Name}"))).Append(");");
- return sb.ToString();
+ if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;");
+
+ 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.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs
index 981e33f9..426f1f16 100644
--- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs
@@ -1,5 +1,7 @@
using FreeSql.Internal;
using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
using System.Text;
@@ -16,28 +18,54 @@ namespace FreeSql.Oracle.Curd
public override string ToSql()
{
if (_source?.Any() != true) return null;
- if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键");
- var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
- .Append("USING (");
- WriteSourceSelectUnionAll(sb);
- sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
+ 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);
- var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
- if (cols.Any())
- sb.Append("WHEN MATCHED THEN \r\n")
- .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
- a.Attribute.IsVersion ?
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
- ))).Append(" \r\n");
+ string getMergeSql(List data)
+ {
+ if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
- cols = _table.Columns.Values;
- 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.{a.Attribute.Name}"))).Append(")");
+ var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING (");
+ WriteSourceSelectUnionAll(data, sb, dbParams);
+ sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
- return sb.ToString();
+ var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
+ if (cols.Any())
+ sb.Append("WHEN MATCHED THEN \r\n")
+ .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
+ a.Attribute.IsVersion ?
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
+ ))).Append(" \r\n");
+
+ cols = _table.Columns.Values;
+ 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.{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.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs
index 87280563..a8a48263 100644
--- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs
@@ -1,4 +1,6 @@
using FreeSql.Internal;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
namespace FreeSql.PostgreSQL.Curd
@@ -15,19 +17,39 @@ namespace FreeSql.PostgreSQL.Curd
{
if (_source?.Any() != true) return null;
- var insert = _orm.Insert()
- .AsTable(_tableRule).AsType(_table.Type)
- .WithConnection(_connection)
- .WithTransaction(_transaction)
- .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
- insert._source = _source;
- var ocdu = new OnConflictDoUpdate(insert);
- ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray());
- if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false)
- ocdu.DoNothing();
- var sql = ocdu.ToSql();
- _params = insert._params;
- return sql;
+ var sqls = new string[2];
+ var dbParams = new List();
+ var ds = SplitSourceByIdentityValueIsNull(_source);
+ if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false);
+ if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true);
+ _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 getInsertSql(List data, bool flagInsert)
+ {
+ var insert = _orm.Insert()
+ .AsTable(_tableRule).AsType(_table.Type)
+ .WithConnection(_connection)
+ .WithTransaction(_transaction)
+ .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
+ insert._source = data;
+
+ string sql = "";
+ if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
+ else
+ {
+ var ocdu = new OnConflictDoUpdate(insert.InsertIdentity());
+ ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray());
+ if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false)
+ ocdu.DoNothing();
+ sql = ocdu.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.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs
index 5e4870d7..f8162605 100644
--- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs
@@ -1,5 +1,7 @@
using FreeSql.Internal;
using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
using System.Text;
@@ -16,28 +18,59 @@ namespace FreeSql.SqlServer.Curd
public override string ToSql()
{
if (_source?.Any() != true) return null;
- if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键");
- var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
+ 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();
+ if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n");
+ sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n")
.Append("USING (");
- WriteSourceSelectUnionAll(sb);
- sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
+ WriteSourceSelectUnionAll(data, sb, dbParams);
+ sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
- var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
- if (cols.Any())
- sb.Append("WHEN MATCHED THEN \r\n")
- .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
- a.Attribute.IsVersion ?
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
- $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
- ))).Append(" \r\n");
+ var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
+ if (cols.Any())
+ sb.Append("WHEN MATCHED THEN \r\n")
+ .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
+ a.Attribute.IsVersion ?
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
+ $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"
+ ))).Append(" \r\n");
- cols = _table.Columns.Values;
- 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.{a.Attribute.Name}"))).Append(");");
+ cols = _table.Columns.Values;
+ 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.{a.Attribute.Name}"))).Append(");");
- return sb.ToString();
+ if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;");
+
+ 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.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs
index 4c6838cb..ba2d2189 100644
--- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs
+++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs
@@ -1,4 +1,7 @@
using FreeSql.Internal;
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
using System.Linq;
namespace FreeSql.Sqlite.Curd
@@ -15,16 +18,35 @@ namespace FreeSql.Sqlite.Curd
{
if (_source?.Any() != true) return null;
- var insert = _orm.Insert()
- .AsTable(_tableRule).AsType(_table.Type)
- .WithConnection(_connection)
- .WithTransaction(_transaction)
- .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
- insert._source = _source;
- var sql = insert.ToSql();
- if (sql.StartsWith("INSERT INTO ") == false) return null;
- _params = insert._params;
- return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}";
+ var sqls = new string[2];
+ var dbParams = new List();
+ var ds = SplitSourceByIdentityValueIsNull(_source);
+ if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false);
+ if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true);
+ _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 getInsertSql(List data, bool flagInsert)
+ {
+ var insert = _orm.Insert()
+ .AsTable(_tableRule).AsType(_table.Type)
+ .WithConnection(_connection)
+ .WithTransaction(_transaction)
+ .NoneParameter(true) as Internal.CommonProvider.InsertProvider;
+ insert._source = data;
+
+ if (IdentityColumn != null && flagInsert == false) insert.InsertIdentity();
+
+ var sql = insert.ToSql();
+ if (string.IsNullOrEmpty(sql)) return null;
+ if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
+ if (IdentityColumn != null && flagInsert) return sql;
+
+ if (sql.StartsWith("INSERT INTO ") == false) return null;
+ return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}";
+ }
}
}
}
\ No newline at end of file