mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 优化未发布的功能 IFreeSql.InsertOrUpdate
This commit is contained in:
		@@ -125,13 +125,6 @@
 | 
				
			|||||||
            清空状态数据
 | 
					            清空状态数据
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSql.DbSet`1.RemoveAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
 | 
					 | 
				
			||||||
            <summary>
 | 
					 | 
				
			||||||
            根据 lambda 条件删除数据
 | 
					 | 
				
			||||||
            </summary>
 | 
					 | 
				
			||||||
            <param name="predicate"></param>
 | 
					 | 
				
			||||||
            <returns></returns>
 | 
					 | 
				
			||||||
        </member>
 | 
					 | 
				
			||||||
        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
					        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            添加
 | 
					            添加
 | 
				
			||||||
@@ -488,14 +481,3 @@
 | 
				
			|||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
    </members>
 | 
					    </members>
 | 
				
			||||||
</doc>
 | 
					</doc>
 | 
				
			||||||
Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
 | 
					 | 
				
			||||||
            <summary>
 | 
					 | 
				
			||||||
            批量注入 Repository,可以参考代码自行调整
 | 
					 | 
				
			||||||
            </summary>
 | 
					 | 
				
			||||||
            <param name="services"></param>
 | 
					 | 
				
			||||||
            <param name="globalDataFilter"></param>
 | 
					 | 
				
			||||||
            <param name="assemblies"></param>
 | 
					 | 
				
			||||||
            <returns></returns>
 | 
					 | 
				
			||||||
        </member>
 | 
					 | 
				
			||||||
    </members>
 | 
					 | 
				
			||||||
</doc>
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,6 +154,149 @@ WHEN NOT MATCHED THEN
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().SetSource(new tbiou022 { name = "01" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "011" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "02" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().SetSource(new tbiou022 { name = "01" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "011" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "02" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,6 +95,93 @@ ON CONFLICT(""id"") DO UPDATE SET
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,6 +154,147 @@ WHEN NOT MATCHED THEN
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().SetSource(new tbiou022 { name = "01" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "011" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "02" });
 | 
				
			||||||
 | 
					            sql = iou.ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql);
 | 
				
			||||||
 | 
					            iou.ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,6 +95,93 @@ ON CONFLICT(""id"") DO UPDATE SET
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -156,6 +156,147 @@ WHEN NOT MATCHED THEN
 | 
				
			|||||||
            public int id { get; set; }
 | 
					            public int id { get; set; }
 | 
				
			||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,6 +81,82 @@ namespace FreeSql.Tests.Sqlite
 | 
				
			|||||||
            public string name { get; set; }
 | 
					            public string name { get; set; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void InsertOrUpdate_OnePrimaryAndIdentity()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var iou = fsql.InsertOrUpdate<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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<tbiou022>().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]
 | 
					        [Fact]
 | 
				
			||||||
        public void InsertOrUpdate_TwoPrimary()
 | 
					        public void InsertOrUpdate_TwoPrimary()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2994,6 +2994,13 @@
 | 
				
			|||||||
            <param name="database"></param>
 | 
					            <param name="database"></param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.Internal.CommonProvider.InsertOrUpdateProvider`1.SplitSourceByIdentityValueIsNull(System.Collections.Generic.List{`0})">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="source"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSql.Internal.CommonProvider.InsertProvider`1.IgnoreCanInsert">
 | 
					        <member name="M:FreeSql.Internal.CommonProvider.InsertProvider`1.IgnoreCanInsert">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            AsType, Ctor, ClearData 三处地方需要重新加载
 | 
					            AsType, Ctor, ClearData 三处地方需要重新加载
 | 
				
			||||||
@@ -3770,6 +3777,7 @@
 | 
				
			|||||||
            Oracle: merge into<para></para>
 | 
					            Oracle: merge into<para></para>
 | 
				
			||||||
            Sqlite: replace into<para></para>
 | 
					            Sqlite: replace into<para></para>
 | 
				
			||||||
            Dameng: merge into<para></para>
 | 
					            Dameng: merge into<para></para>
 | 
				
			||||||
 | 
					            注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
            <typeparam name="T1"></typeparam>
 | 
					            <typeparam name="T1"></typeparam>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
        protected DbParameter[] _params;
 | 
					        protected DbParameter[] _params;
 | 
				
			||||||
        protected DbTransaction _transaction;
 | 
					        protected DbTransaction _transaction;
 | 
				
			||||||
        protected DbConnection _connection;
 | 
					        protected DbConnection _connection;
 | 
				
			||||||
 | 
					        public ColumnInfo IdentityColumn { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
 | 
					        public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -33,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            _commonExpression = commonExpression;
 | 
					            _commonExpression = commonExpression;
 | 
				
			||||||
            _table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
					            _table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
				
			||||||
            if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
 | 
					            if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
 | 
				
			||||||
 | 
					            IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected void ClearData()
 | 
					        protected void ClearData()
 | 
				
			||||||
@@ -130,11 +132,10 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void WriteSourceSelectUnionAll(StringBuilder sb)
 | 
					        public void WriteSourceSelectUnionAll(List<T1> source, StringBuilder sb, List<DbParameter> dbParams)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var specialParams = new List<DbParameter>();
 | 
					 | 
				
			||||||
            var didx = 0;
 | 
					            var didx = 0;
 | 
				
			||||||
            foreach (var d in _source)
 | 
					            foreach (var d in source)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (didx > 0) sb.Append(" \r\nUNION ALL\r\n ");
 | 
					                if (didx > 0) sb.Append(" \r\nUNION ALL\r\n ");
 | 
				
			||||||
                sb.Append("SELECT ");
 | 
					                sb.Append("SELECT ");
 | 
				
			||||||
@@ -147,7 +148,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        object val = col.GetMapValue(d);
 | 
					                        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);
 | 
					                    if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name);
 | 
				
			||||||
                    ++colidx2;
 | 
					                    ++colidx2;
 | 
				
			||||||
@@ -163,11 +164,82 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                ++didx;
 | 
					                ++didx;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (specialParams.Any()) _params = specialParams.ToArray();
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        byte _SplitSourceByIdentityValueIsNullFlag = 0; //防止重复计算 SplitSource
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="source"></param>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public NaviteTuple<List<T1>, List<T1>> SplitSourceByIdentityValueIsNull(List<T1> source)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_SplitSourceByIdentityValueIsNullFlag == 1) return NaviteTuple.Create(source, new List<T1>());
 | 
				
			||||||
 | 
					            if (_SplitSourceByIdentityValueIsNullFlag == 2) return NaviteTuple.Create(new List<T1>(), source);
 | 
				
			||||||
 | 
					            if (IdentityColumn == null) return NaviteTuple.Create(source, new List<T1>());
 | 
				
			||||||
 | 
					            var ret = NaviteTuple.Create(new List<T1>(), new List<T1>());
 | 
				
			||||||
 | 
					            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 abstract string ToSql();
 | 
				
			||||||
        public int ExecuteAffrows()
 | 
					        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();
 | 
					            var sql = this.ToSql();
 | 
				
			||||||
            if (string.IsNullOrEmpty(sql)) return 0;
 | 
					            if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
@@ -193,7 +265,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
#if net40
 | 
					#if net40
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        async public Task<int> ExecuteAffrowsAsync()
 | 
					        async public Task<int> RawExecuteAffrowsAsync()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var sql = this.ToSql();
 | 
					            var sql = this.ToSql();
 | 
				
			||||||
            if (string.IsNullOrEmpty(sql)) return 0;
 | 
					            if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
@@ -217,6 +289,56 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            return affrows;
 | 
					            return affrows;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        async public Task<int> 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
 | 
					#endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,11 +18,23 @@ namespace FreeSql.Dameng.Curd
 | 
				
			|||||||
        public override string ToSql()
 | 
					        public override string ToSql()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            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];
 | 
				
			||||||
                .Append("USING (");
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
            WriteSourceSelectUnionAll(sb);
 | 
					            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<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\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");
 | 
					                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);
 | 
					                var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
 | 
				
			||||||
@@ -39,5 +53,19 @@ namespace FreeSql.Dameng.Curd
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return sb.ToString();
 | 
					                return sb.ToString();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            string getInsertSql(List<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
 | 
					                insert._source = data;
 | 
				
			||||||
 | 
					                var sql = insert.ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
 | 
					                return sql;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,9 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.MySql.Curd
 | 
					namespace FreeSql.MySql.Curd
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -15,15 +19,32 @@ namespace FreeSql.MySql.Curd
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            if (_source?.Any() != true) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var sqls = new string[2];
 | 
				
			||||||
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
 | 
					            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<T1> data, bool flagInsert)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var insert = _orm.Insert<T1>()
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
                    .AsTable(_tableRule).AsType(_table.Type)
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
                    .WithConnection(_connection)
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
                    .WithTransaction(_transaction)
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
            insert._source = _source;
 | 
					                insert._source = data;
 | 
				
			||||||
            var sql = new OnDuplicateKeyUpdate<T1>(insert).ToSql();
 | 
					
 | 
				
			||||||
            _params = insert._params;
 | 
					                string sql = "";
 | 
				
			||||||
 | 
					                if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
 | 
				
			||||||
 | 
					                else sql = new OnDuplicateKeyUpdate<T1>(insert.InsertIdentity()).ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
                return sql;
 | 
					                return sql;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,11 +18,23 @@ namespace FreeSql.Odbc.Dameng
 | 
				
			|||||||
        public override string ToSql()
 | 
					        public override string ToSql()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            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];
 | 
				
			||||||
                .Append("USING (");
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
            WriteSourceSelectUnionAll(sb);
 | 
					            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<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\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");
 | 
					                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);
 | 
					                var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
 | 
				
			||||||
@@ -39,5 +53,19 @@ namespace FreeSql.Odbc.Dameng
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return sb.ToString();
 | 
					                return sb.ToString();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            string getInsertSql(List<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
 | 
					                insert._source = data;
 | 
				
			||||||
 | 
					                var sql = insert.ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
 | 
					                return sql;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.Odbc.MySql
 | 
					namespace FreeSql.Odbc.MySql
 | 
				
			||||||
@@ -15,15 +17,32 @@ namespace FreeSql.Odbc.MySql
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            if (_source?.Any() != true) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var sqls = new string[2];
 | 
				
			||||||
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
 | 
					            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<T1> data, bool flagInsert)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var insert = _orm.Insert<T1>()
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
                    .AsTable(_tableRule).AsType(_table.Type)
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
                    .WithConnection(_connection)
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
                    .WithTransaction(_transaction)
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
            insert._source = _source;
 | 
					                insert._source = data;
 | 
				
			||||||
            var sql = new OdbcMySqlOnDuplicateKeyUpdate<T1>(insert).ToSql();
 | 
					
 | 
				
			||||||
            _params = insert._params;
 | 
					                string sql = "";
 | 
				
			||||||
 | 
					                if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
 | 
				
			||||||
 | 
					                else sql = new OdbcMySqlOnDuplicateKeyUpdate<T1>(insert.InsertIdentity()).ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
                return sql;
 | 
					                return sql;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,11 +18,23 @@ namespace FreeSql.Odbc.Oracle
 | 
				
			|||||||
        public override string ToSql()
 | 
					        public override string ToSql()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            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];
 | 
				
			||||||
                .Append("USING (");
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
            WriteSourceSelectUnionAll(sb);
 | 
					            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<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\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");
 | 
					                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);
 | 
					                var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
 | 
				
			||||||
@@ -39,5 +53,19 @@ namespace FreeSql.Odbc.Oracle
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return sb.ToString();
 | 
					                return sb.ToString();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            string getInsertSql(List<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
 | 
					                insert._source = data;
 | 
				
			||||||
 | 
					                var sql = insert.ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
 | 
					                return sql;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.Odbc.PostgreSQL
 | 
					namespace FreeSql.Odbc.PostgreSQL
 | 
				
			||||||
@@ -15,19 +17,39 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            if (_source?.Any() != true) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var sqls = new string[2];
 | 
				
			||||||
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
 | 
					            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<T1> data, bool flagInsert)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var insert = _orm.Insert<T1>()
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
                    .AsTable(_tableRule).AsType(_table.Type)
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
                    .WithConnection(_connection)
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
                    .WithTransaction(_transaction)
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
            insert._source = _source;
 | 
					                insert._source = data;
 | 
				
			||||||
            var ocdu = new OdbcPostgreSQLOnConflictDoUpdate<T1>(insert);
 | 
					
 | 
				
			||||||
 | 
					                string sql = "";
 | 
				
			||||||
 | 
					                if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var ocdu = new OdbcPostgreSQLOnConflictDoUpdate<T1>(insert.InsertIdentity());
 | 
				
			||||||
                    ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray());
 | 
					                    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)
 | 
					                    if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false)
 | 
				
			||||||
                        ocdu.DoNothing();
 | 
					                        ocdu.DoNothing();
 | 
				
			||||||
            var sql = ocdu.ToSql();
 | 
					                    sql = ocdu.ToSql();
 | 
				
			||||||
            _params = insert._params;
 | 
					                }
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
                return sql;
 | 
					                return sql;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,11 +18,26 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
        public override string ToSql()
 | 
					        public override string ToSql()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            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<DbParameter>();
 | 
				
			||||||
 | 
					            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<T1> 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 (");
 | 
					                .Append("USING (");
 | 
				
			||||||
            WriteSourceSelectUnionAll(sb);
 | 
					                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");
 | 
					                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);
 | 
					                var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
 | 
				
			||||||
@@ -37,7 +54,23 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
                    .Append("  insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \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(");");
 | 
					                    .Append("  values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return sb.ToString();
 | 
					                return sb.ToString();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            string getInsertSql(List<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
 | 
					                insert._source = data;
 | 
				
			||||||
 | 
					                var sql = insert.ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
 | 
					                return sql;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,11 +18,23 @@ namespace FreeSql.Oracle.Curd
 | 
				
			|||||||
        public override string ToSql()
 | 
					        public override string ToSql()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            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];
 | 
				
			||||||
                .Append("USING (");
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
            WriteSourceSelectUnionAll(sb);
 | 
					            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<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\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");
 | 
					                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);
 | 
					                var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
 | 
				
			||||||
@@ -39,5 +53,19 @@ namespace FreeSql.Oracle.Curd
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return sb.ToString();
 | 
					                return sb.ToString();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            string getInsertSql(List<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
 | 
					                insert._source = data;
 | 
				
			||||||
 | 
					                var sql = insert.ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
 | 
					                return sql;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.PostgreSQL.Curd
 | 
					namespace FreeSql.PostgreSQL.Curd
 | 
				
			||||||
@@ -15,19 +17,39 @@ namespace FreeSql.PostgreSQL.Curd
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            if (_source?.Any() != true) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var sqls = new string[2];
 | 
				
			||||||
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
 | 
					            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<T1> data, bool flagInsert)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var insert = _orm.Insert<T1>()
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
                    .AsTable(_tableRule).AsType(_table.Type)
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
                    .WithConnection(_connection)
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
                    .WithTransaction(_transaction)
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
            insert._source = _source;
 | 
					                insert._source = data;
 | 
				
			||||||
            var ocdu = new OnConflictDoUpdate<T1>(insert);
 | 
					
 | 
				
			||||||
 | 
					                string sql = "";
 | 
				
			||||||
 | 
					                if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var ocdu = new OnConflictDoUpdate<T1>(insert.InsertIdentity());
 | 
				
			||||||
                    ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray());
 | 
					                    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)
 | 
					                    if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false)
 | 
				
			||||||
                        ocdu.DoNothing();
 | 
					                        ocdu.DoNothing();
 | 
				
			||||||
            var sql = ocdu.ToSql();
 | 
					                    sql = ocdu.ToSql();
 | 
				
			||||||
            _params = insert._params;
 | 
					                }
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
                return sql;
 | 
					                return sql;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,11 +18,26 @@ namespace FreeSql.SqlServer.Curd
 | 
				
			|||||||
        public override string ToSql()
 | 
					        public override string ToSql()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            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<DbParameter>();
 | 
				
			||||||
 | 
					            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<T1> 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 (");
 | 
					                .Append("USING (");
 | 
				
			||||||
            WriteSourceSelectUnionAll(sb);
 | 
					                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");
 | 
					                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);
 | 
					                var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
 | 
				
			||||||
@@ -37,7 +54,23 @@ namespace FreeSql.SqlServer.Curd
 | 
				
			|||||||
                    .Append("  insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \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(");");
 | 
					                    .Append("  values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return sb.ToString();
 | 
					                return sb.ToString();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            string getInsertSql(List<T1> data)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
 | 
					                insert._source = data;
 | 
				
			||||||
 | 
					                var sql = insert.ToSql();
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(sql)) return null;
 | 
				
			||||||
 | 
					                if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
 | 
				
			||||||
 | 
					                return sql;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.Sqlite.Curd
 | 
					namespace FreeSql.Sqlite.Curd
 | 
				
			||||||
@@ -15,16 +18,35 @@ namespace FreeSql.Sqlite.Curd
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_source?.Any() != true) return null;
 | 
					            if (_source?.Any() != true) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var sqls = new string[2];
 | 
				
			||||||
 | 
					            var dbParams = new List<DbParameter>();
 | 
				
			||||||
 | 
					            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<T1> data, bool flagInsert)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var insert = _orm.Insert<T1>()
 | 
					                var insert = _orm.Insert<T1>()
 | 
				
			||||||
                    .AsTable(_tableRule).AsType(_table.Type)
 | 
					                    .AsTable(_tableRule).AsType(_table.Type)
 | 
				
			||||||
                    .WithConnection(_connection)
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
                    .WithTransaction(_transaction)
 | 
					                    .WithTransaction(_transaction)
 | 
				
			||||||
                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
					                    .NoneParameter(true) as Internal.CommonProvider.InsertProvider<T1>;
 | 
				
			||||||
            insert._source = _source;
 | 
					                insert._source = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (IdentityColumn != null && flagInsert == false) insert.InsertIdentity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var sql = insert.ToSql();
 | 
					                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;
 | 
					                if (sql.StartsWith("INSERT INTO ") == false) return null;
 | 
				
			||||||
            _params = insert._params;
 | 
					 | 
				
			||||||
                return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}";
 | 
					                return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user