- 增加 PostgreSQL 特有功能 On Conflict Do Update 功能;

This commit is contained in:
28810
2019-11-13 16:21:30 +08:00
parent b43f9b6688
commit e0030b0c00
10 changed files with 492 additions and 35 deletions

View File

@ -99,7 +99,7 @@
总分
</summary>
</member>
<member name="P:FreeSql.Tests.UnitTest2.SysModulePermission.SysModulePermissionId">
<member name="P:FreeSql.Tests.UnitTest2.SysModulePermission.Id">
<summary>
菜单权限ID
</summary>
@ -119,7 +119,7 @@
菜单权限
</summary>
</member>
<member name="P:FreeSql.Tests.UnitTest2.SysModule.SysModuleId">
<member name="P:FreeSql.Tests.UnitTest2.SysModule.Id">
<summary>
主键
</summary>
@ -164,7 +164,7 @@
创建日期
</summary>
</member>
<member name="P:FreeSql.Tests.UnitTest2.SysModuleButton.SysModuleButtonId">
<member name="P:FreeSql.Tests.UnitTest2.SysModuleButton.Id">
<summary>
按钮主键
</summary>

View File

@ -0,0 +1,201 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace FreeSql.Tests.PostgreSQL
{
public class OnConflictDoUpdateTest
{
class TestOnConflictDoUpdateInfo
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string title { get; set; }
public DateTime? time { get; set; }
}
[Fact]
public void ExecuteAffrows()
{
g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 100, 101, 102 }).ExecuteAffrows();
var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate();
Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000')
ON CONFLICT(""id"") DO UPDATE SET
""title"" = EXCLUDED.""title"",
""time"" = EXCLUDED.""time""");
Assert.Equal(1, odku1.ExecuteAffrows());
var odku2 = g.pgsql.Insert(new[] {
new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") }
}).NoneParameter().OnConflictDoUpdate();
Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000')
ON CONFLICT(""id"") DO UPDATE SET
""title"" = EXCLUDED.""title"",
""time"" = EXCLUDED.""time""");
odku2.ExecuteAffrows();
}
[Fact]
public void IgnoreColumns()
{
g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 200, 201, 202 }).ExecuteAffrows();
var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate();
Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200')
ON CONFLICT(""id"") DO UPDATE SET
""title"" = EXCLUDED.""title"",
""time"" = '2000-01-01 00:00:00.000000'");
Assert.Equal(1, odku1.ExecuteAffrows());
var odku2 = g.pgsql.Insert(new[] {
new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") }
}).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate();
Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202')
ON CONFLICT(""id"") DO UPDATE SET
""title"" = EXCLUDED.""title"",
""time"" = CASE EXCLUDED.""id""
WHEN 200 THEN '2000-01-01 00:00:00.000000'
WHEN 201 THEN '2000-01-01 00:00:00.000000'
WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp");
odku2.ExecuteAffrows();
g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 200, 201, 202 }).ExecuteAffrows();
odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate().IgnoreColumns(a => a.title);
Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200')
ON CONFLICT(""id"") DO UPDATE SET
""time"" = '2000-01-01 00:00:00.000000'");
Assert.Equal(1, odku1.ExecuteAffrows());
odku2 = g.pgsql.Insert(new[] {
new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") }
}).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate().IgnoreColumns(a => a.title);
Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202')
ON CONFLICT(""id"") DO UPDATE SET
""time"" = CASE EXCLUDED.""id""
WHEN 200 THEN '2000-01-01 00:00:00.000000'
WHEN 201 THEN '2000-01-01 00:00:00.000000'
WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp");
odku2.ExecuteAffrows();
}
[Fact]
public void UpdateColumns()
{
g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 300, 301, 302 }).ExecuteAffrows();
var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate();
Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300')
ON CONFLICT(""id"") DO UPDATE SET
""title"" = EXCLUDED.""title"",
""time"" = '2000-01-01 00:00:00.000000'");
Assert.Equal(1, odku1.ExecuteAffrows());
var odku2 = g.pgsql.Insert(new[] {
new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") }
}).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate();
Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302')
ON CONFLICT(""id"") DO UPDATE SET
""title"" = EXCLUDED.""title"",
""time"" = CASE EXCLUDED.""id""
WHEN 300 THEN '2000-01-01 00:00:00.000000'
WHEN 301 THEN '2000-01-01 00:00:00.000000'
WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp");
odku2.ExecuteAffrows();
g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 300, 301, 302 }).ExecuteAffrows();
odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate().UpdateColumns(a => a.time);
Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300')
ON CONFLICT(""id"") DO UPDATE SET
""time"" = '2000-01-01 00:00:00.000000'");
Assert.Equal(1, odku1.ExecuteAffrows());
odku2 = g.pgsql.Insert(new[] {
new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") }
}).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate().UpdateColumns(a => a.time);
Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302')
ON CONFLICT(""id"") DO UPDATE SET
""time"" = CASE EXCLUDED.""id""
WHEN 300 THEN '2000-01-01 00:00:00.000000'
WHEN 301 THEN '2000-01-01 00:00:00.000000'
WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp");
odku2.ExecuteAffrows();
}
[Fact]
public void Set()
{
g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 400, 401, 402 }).ExecuteAffrows();
var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => a.time, DateTime.Parse("2020-1-1"));
Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000')
ON CONFLICT(""id"") DO UPDATE SET
""time"" = '2020-01-01 00:00:00.000000'");
Assert.Equal(1, odku1.ExecuteAffrows());
var odku2 = g.pgsql.Insert(new[] {
new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") },
new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") }
}).NoneParameter().OnConflictDoUpdate().Set(a => a.time, DateTime.Parse("2020-1-1"));
Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000')
ON CONFLICT(""id"") DO UPDATE SET
""time"" = '2020-01-01 00:00:00.000000'");
odku2.ExecuteAffrows();
// var dt2020 = DateTime.Parse("2020-1-1");
// g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 400, 401, 402 }).ExecuteAffrows();
// odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => a.time == dt2020);
// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000')
//ON CONFLICT(""id"") DO UPDATE SET
//""time"" = '2020-01-01 00:00:00.000000'");
// Assert.Equal(1, odku1.ExecuteAffrows());
// odku2 = g.pgsql.Insert(new[] {
// new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") },
// new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") },
// new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") }
// }).NoneParameter().OnConflictDoUpdate().Set(a => a.time == dt2020);
// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000')
//ON CONFLICT(""id"") DO UPDATE SET
//""time"" = '2020-01-01 00:00:00.000000'");
// odku2.ExecuteAffrows();
// g.pgsql.Delete<TestOnConflictDoUpdateInfo>(new[] { 400, 401, 402 }).ExecuteAffrows();
// odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => new { time = dt2020, title = a.title + "123" });
// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000')
//ON CONFLICT(""id"") DO UPDATE SET
//""time"" = '2020-01-01 00:00:00.000000', ""title"" = _ftb_.""title"" || '123'");
// Assert.Equal(1, odku1.ExecuteAffrows());
// odku2 = g.pgsql.Insert(new[] {
// new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") },
// new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") },
// new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") }
// }).NoneParameter().OnConflictDoUpdate().Set(a => new { time = dt2020, title = a.title + "123" });
// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000')
//ON CONFLICT(""id"") DO UPDATE SET
//""time"" = '2020-01-01 00:00:00.000000', ""title"" = _ftb_.""title"" || '123'");
// odku2.ExecuteAffrows();
}
[Fact]
public void SetRaw()
{
}
}
}

View File

@ -427,6 +427,10 @@ namespace FreeSql.Tests
[Fact]
public void Test1()
{
g.sqlite.Update<Model1>(1).NoneParameter().Set(a => a.title, null).ExecuteAffrows();
var testExNewRet1 = g.sqlite.Delete<TestAddEnumEx>().Where("1=1").ExecuteAffrows();
var testExNewRet2 = g.sqlite.Insert<TestAddEnumEx>(new TestAddEnumEx { Id = 1, Type = TestAddEnumType. }).ExecuteAffrows();
var testExNewRet3 = g.sqlite.Insert<TestAddEnumEx>(new TestAddEnumEx { Id = 2, Type = TestAddEnumType. }).ExecuteAffrows();
@ -858,8 +862,6 @@ namespace FreeSql.Tests
var ttt1 = g.sqlite.Select<Model1>().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList();

View File

@ -21,7 +21,8 @@ namespace FreeSql.Tests
/// <summary>
/// 菜单权限ID
/// </summary>
[Column(IsPrimary = true)] public String SysModulePermissionId { get; set; }
[Column(IsPrimary = true, OldName = "SysModulePermissionId")]
public String Id { get; set; }
/// <summary>
/// 菜单主键ID
@ -43,8 +44,8 @@ namespace FreeSql.Tests
/// <summary>
/// 主键
/// </summary>
[Column(IsPrimary = true)]
public String SysModuleId { get; set; }
[Column(IsPrimary = true, OldName = "SysModuleId")]
public String Id { get; set; }
/// <summary>
/// 父级ID
@ -92,8 +93,8 @@ namespace FreeSql.Tests
/// <summary>
/// 按钮主键
/// </summary>
[Column(IsPrimary = true)]
public String SysModuleButtonId { get; set; }
[Column(IsPrimary = true, OldName = "SysModuleButtonId")]
public String Id { get; set; }
/// <summary>
/// 名称
@ -127,10 +128,12 @@ namespace FreeSql.Tests
}
partial class SysModulePermission
{
[Navigate("SysModuleButtonId")]
public SysModuleButton Button { get; set; }
}
partial class SysModule
{
[Navigate("SysModuleId")]
public List<SysModulePermission> Permissions { get; set; }
}
partial class SysModuleButton
@ -164,10 +167,25 @@ namespace FreeSql.Tests
[Fact]
public void Test02()
{
var list111 = g.sqlite.Select<SysModule>()
.Page(1, 10)
.ToList(a => new { Id = a.Id })
.Select(a => new SysModule { Id = a.Id }).ToList()
.IncludeMany(g.sqlite, a => a.Permissions, then => then.Include(a => a.Button));
var list222 = g.sqlite.Select<SysModule>()
.IncludeMany(m => m.Permissions, then => then.Include(a => a.Button))
.Page(1, 10)
.ToList();
var comments1 = g.mysql.Select<Comment, UserLike>()
.LeftJoin((a, b) => a.Id == b.SubjectId)
.ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo });
.LeftJoin((a, b) => a.Id == b.SubjectId)
.ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo });
var comments2 = g.mysql.Select<Comment>()
.Include(r => r.UserInfo)
@ -178,36 +196,32 @@ namespace FreeSql.Tests
g.sqlite.Delete<SysModuleButton>().Where("1=1").ExecuteAffrows();
g.sqlite.Delete<SysModule>().Where("1=1").ExecuteAffrows();
var menu1 = new SysModule { SysModuleId = "menu1", Name = "菜单1" };
var menu2 = new SysModule { SysModuleId = "menu2", Name = "菜单2" };
var menu1 = new SysModule { Id = "menu1", Name = "菜单1" };
var menu2 = new SysModule { Id = "menu2", Name = "菜单2" };
g.sqlite.Insert(new[] { menu1, menu2 }).ExecuteAffrows();
var button1 = new SysModuleButton { SysModuleButtonId = "button1", Name = "添加" };
var button2 = new SysModuleButton { SysModuleButtonId = "button2", Name = "修改" };
var button3 = new SysModuleButton { SysModuleButtonId = "button3", Name = "删除" };
var button4 = new SysModuleButton { SysModuleButtonId = "button4", Name = "查询" };
var button1 = new SysModuleButton { Id = "button1", Name = "添加" };
var button2 = new SysModuleButton { Id = "button2", Name = "修改" };
var button3 = new SysModuleButton { Id = "button3", Name = "删除" };
var button4 = new SysModuleButton { Id = "button4", Name = "查询" };
g.sqlite.Insert(new[] { button1, button2, button3, button4 }).ExecuteAffrows();
g.sqlite.Insert(new[] {
new SysModulePermission { SysModulePermissionId = "menu1_button1", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button1.SysModuleButtonId },
new SysModulePermission { SysModulePermissionId = "menu1_button2", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button2.SysModuleButtonId },
new SysModulePermission { SysModulePermissionId = "menu1_button3", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button3.SysModuleButtonId },
new SysModulePermission { SysModulePermissionId = "menu1_button4", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button4.SysModuleButtonId },
new SysModulePermission { Id = "menu1_button1", SysModuleId = menu1.Id, SysModuleButtonId = button1.Id },
new SysModulePermission { Id = "menu1_button2", SysModuleId = menu1.Id, SysModuleButtonId = button2.Id },
new SysModulePermission { Id = "menu1_button3", SysModuleId = menu1.Id, SysModuleButtonId = button3.Id },
new SysModulePermission { Id = "menu1_button4", SysModuleId = menu1.Id, SysModuleButtonId = button4.Id },
new SysModulePermission { SysModulePermissionId = "menu2_button1", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button1.SysModuleButtonId },
new SysModulePermission { SysModulePermissionId = "menu2_button2", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button2.SysModuleButtonId },
new SysModulePermission { SysModulePermissionId = "menu2_button3", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button3.SysModuleButtonId },
new SysModulePermission { SysModulePermissionId = "menu2_button4", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button4.SysModuleButtonId },
new SysModulePermission { Id = "menu2_button1", SysModuleId = menu2.Id, SysModuleButtonId = button1.Id },
new SysModulePermission { Id = "menu2_button2", SysModuleId = menu2.Id, SysModuleButtonId = button2.Id },
new SysModulePermission { Id = "menu2_button3", SysModuleId = menu2.Id, SysModuleButtonId = button3.Id },
new SysModulePermission { Id = "menu2_button4", SysModuleId = menu2.Id, SysModuleButtonId = button4.Id },
}).ExecuteAffrows();
//var list = g.sqlite.Select<SysModule>()
// .IncludeMany(m => m.Buttons)
// .Page(1, 10)
// .ToList();
var list = g.sqlite.Select<SysModule>()
.IncludeMany(m => m.Permissions.Where(p => p.SysModuleId == m.SysModuleId),
then => then.LeftJoin(p => p.Button.SysModuleButtonId == p.SysModuleButtonId))
var list123123 = g.sqlite.Select<SysModule>()
.IncludeMany(m => m.Permissions.Where(p => p.SysModuleId == m.Id),
then => then.LeftJoin(p => p.Button.Id == p.SysModuleButtonId))
.ToList();
}
}