diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs index 45f141891..b501abf94 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -1,4 +1,5 @@ using FreeSql.DataAnnotations; +using FreeSql.PostgreSQL; using System; using System.Collections.Generic; using System.Linq; @@ -120,6 +121,7 @@ ON CONFLICT(""name"") DO UPDATE SET Assert.Equal(1, iou2); } + [Index("uix_tbiou_temp_name", "name", true)] class tbiou_temp { @@ -322,5 +324,41 @@ ON CONFLICT(""id"") DO UPDATE SET [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] public DateTime CreateTime { get; set; } } + + class tbiou05 + { + [Column(IsIdentity = true, IsPrimary = true)] + public int id { get; set; } + public string name { get; set; } + + public byte[] data { get; set; } + } + + [Fact] + public void InsertOrUpdate_Blob() + { + var pgsql = g.opengauss; + (pgsql as IPostgreSQLProviderOptions).UseMergeInto = true; + var iou = pgsql.InsertOrUpdate().SetSource(new tbiou05 { name = "01", data = null, id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""tbiou05"" t1 +USING (SELECT 1 as ""id"", '01' as ""name"", NULL::bytea as ""data"" ) t2 ON (t1.""id"" = t2.""id"") +WHEN MATCHED THEN + update set ""name"" = t2.""name"", ""data"" = t2.""data"" +WHEN NOT MATCHED THEN + insert (""id"", ""name"", ""data"") + values (t2.""id"", t2.""name"", t2.""data"");", sql); + + var tbiou1 = new tbiou05 { id = 1, name = "01", data = new byte[] { 1, 2, 3, 4, 5, 6 } }; + var iou2 = pgsql.InsertOrUpdate().SetSource(tbiou1); + var sql2 = iou2.ToSql(); + Assert.Equal(@"MERGE INTO ""tbiou05"" t1 +USING (SELECT 1 as ""id"", '01' as ""name"", '\x010203040506'::bytea as ""data"" ) t2 ON (t1.""id"" = t2.""id"") +WHEN MATCHED THEN + update set ""name"" = t2.""name"", ""data"" = t2.""data"" +WHEN NOT MATCHED THEN + insert (""id"", ""name"", ""data"") + values (t2.""id"", t2.""name"", t2.""data"");", sql2); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index c35216a2f..29832ccd6 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -22,9 +22,9 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5;Allow User Variables=True") - //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;")) - //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=33061;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") - .UseAutoSyncStructure(true) + //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;")) + //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=33061;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") + .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 @@ -39,8 +39,8 @@ public class g NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); return new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=127.0.0.1;Port=5432;Username=postgres;Password=123456;Database=tedb;ArrayNullabilityMode=Always;Pooling=true;Maximum Pool Size=2") - //.UseConnectionFactory(FreeSql.DataType.PostgreSQL, () => new Npgsql.NpgsqlConnection("Host=127.0.0.1;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;")) - .UseAutoSyncStructure(true) + //.UseConnectionFactory(FreeSql.DataType.PostgreSQL, () => new Npgsql.NpgsqlConnection("Host=127.0.0.1;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;")) + .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) .UseLazyLoading(true) @@ -52,6 +52,18 @@ public class g }); public static IFreeSql pgsql => pgsqlLazy.Value; + static Lazy opengaussLazy = new Lazy(() => + { + return new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=127.0.0.1;Port=5432;Username=postgres;Password=123456;Database=tedb;ArrayNullabilityMode=Always;Pooling=true;Maximum Pool Size=2;No Reset On Close=true;") + .UseAutoSyncStructure(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + .UseLazyLoading(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build(); + }); + public static IFreeSql opengauss => opengaussLazy.Value; + static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=issues684;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") .UseAutoSyncStructure(true) @@ -133,7 +145,8 @@ public class g static Lazy shentongLazy = new Lazy(() => { - var connString = new System.Data.OscarClient.OscarConnectionStringBuilder { + var connString = new System.Data.OscarClient.OscarConnectionStringBuilder + { Host = "192.168.164.10", Port = 2003, UserName = "SYSDBA", diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index 3684d5d6d..507b82c03 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -111,11 +111,9 @@ namespace FreeSql.PostgreSQL.Curd var tempPrimaryIsIdentity = _tempPrimarys.Any(b => b.Attribute.IsIdentity); var sb = new StringBuilder(); - if (IdentityColumn != null && tempPrimaryIsIdentity) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) || _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) @@ -140,9 +138,6 @@ namespace FreeSql.PostgreSQL.Curd if (tempPrimaryIsIdentity == false && a.Attribute.IsIdentity && string.IsNullOrEmpty(a.DbInsertValue) == false) return a.DbInsertValue; return $"t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"; }))).Append(");"); - - if (IdentityColumn != null && tempPrimaryIsIdentity) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;"); - return sb.ToString(); } string getInsertSql(List data) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index cd70fb1d6..5f8a2b48e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -195,7 +195,7 @@ namespace FreeSql.PostgreSQL } value = getParamterValue(type, value); var type2 = value.GetType(); - if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'::bytea"; if (value is Array) { var valueArr = value as Array;