- 完善 BulkCopy Update

This commit is contained in:
2881099 2022-12-06 21:57:30 +08:00
parent 768b715e18
commit 09864eaa9f
12 changed files with 269 additions and 136 deletions

View File

@ -23,8 +23,8 @@ namespace orm_vs
{ {
static IFreeSql fsql = new FreeSql.FreeSqlBuilder() static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=tedb1;Pooling=true;Max Pool Size=21;TrustServerCertificate=true") .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=tedb1;Pooling=true;Max Pool Size=21;TrustServerCertificate=true")
.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=21;AllowLoadLocalInfile=true;") //.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=21;AllowLoadLocalInfile=true;")
.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=21") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=21")
.UseAutoSyncStructure(false) .UseAutoSyncStructure(false)
.UseNoneCommandParameter(true) .UseNoneCommandParameter(true)
//.UseConfigEntityFromDbFirst(true) //.UseConfigEntityFromDbFirst(true)
@ -36,12 +36,12 @@ namespace orm_vs
{ {
var db = new SqlSugarClient(new ConnectionConfig() var db = new SqlSugarClient(new ConnectionConfig()
{ {
//ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=tedb1;Pooling=true;Min Pool Size=20;Max Pool Size=20;TrustServerCertificate=true", ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=tedb1;Pooling=true;Min Pool Size=20;Max Pool Size=20;TrustServerCertificate=true",
//DbType = DbType.SqlServer, DbType = DbType.SqlServer,
//ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20;AllowLoadLocalInfile=true;", //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20;AllowLoadLocalInfile=true;",
//DbType = DbType.MySql, //DbType = DbType.MySql,
ConnectionString = "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=20", //ConnectionString = "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=20",
DbType = DbType.PostgreSQL, //DbType = DbType.PostgreSQL,
IsAutoCloseConnection = true, IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute InitKeyType = InitKeyType.Attribute
}); });
@ -59,10 +59,10 @@ namespace orm_vs
public DbSet<PatientExamination_2022> PatientExamination_2022s { get; set; } public DbSet<PatientExamination_2022> PatientExamination_2022s { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
//optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=tedb1;Pooling=true;Min Pool Size=19;Max Pool Size=19;TrustServerCertificate=true"); optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=tedb1;Pooling=true;Min Pool Size=19;Max Pool Size=19;TrustServerCertificate=true");
//var connectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=19;Max Pool Size=19"; //var connectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=19;Max Pool Size=19";
//optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); //optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
optionsBuilder.UseNpgsql("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=19"); //optionsBuilder.UseNpgsql("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=19");
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
@ -576,14 +576,14 @@ namespace orm_vs
sw.Stop(); sw.Stop();
sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms .net5.0无效"); sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms .net5.0无效");
sw.Restart(); //sw.Restart();
using (var conn = fsql.Ado.MasterPool.Get()) //using (var conn = fsql.Ado.MasterPool.Get())
{ //{
for (var a = 0; a < forTime; a++) // for (var a = 0; a < forTime; a++)
Dapper.SqlMapper.Query<Song>(conn.Value, $"select * from freesql_song limit {size}").ToList(); // Dapper.SqlMapper.Query<Song>(conn.Value, $"select * from freesql_song limit {size}").ToList();
} //}
sw.Stop(); //sw.Stop();
sb.AppendLine($"Dapper Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); //sb.AppendLine($"Dapper Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n");
} }
static void Insert(StringBuilder sb, int forTime, int size) static void Insert(StringBuilder sb, int forTime, int size)
@ -668,7 +668,7 @@ namespace orm_vs
sw.Restart(); sw.Restart();
for (var a = 0; a < forTime; a++) for (var a = 0; a < forTime; a++)
{ {
fsql.Update<Song>().SetSource(songs).ExecutePgCopy(); fsql.Update<Song>().SetSource(songs).ExecuteSqlBulkCopy();
} }
sw.Stop(); sw.Stop();
sb.AppendLine($"FreeSql BulkCopyUpdate {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); sb.AppendLine($"FreeSql BulkCopyUpdate {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms");

View File

@ -1,4 +1,4 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -181,6 +181,32 @@ namespace FreeSql.Tests.MySqlConnector
Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select<TestEnumInsertTb>().Where(a => a.id == id).First()?.type); Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select<TestEnumInsertTb>().Where(a => a.id == id).First()?.type);
} }
[Table(Name = "tb_topic_insertbulk")]
class TopicBulk
{
[Column(IsIdentity = true, IsPrimary = true)]
public int Id { get; set; }
public int Clicks { get; set; }
public string Title { get; set; }
public DateTime CreateTime { get; set; }
}
[Fact]
public void ExecuteMySqlBulkCopy()
{
g.mysql.Delete<TopicBulk>().Where(a => true).ExecuteAffrows();
var items = new List<TopicBulk>();
for (var a = 0; a < 10; a++) items.Add(new TopicBulk { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
g.mysql.Insert(items).ExecuteMySqlBulkCopy();
items = g.mysql.Select<TopicBulk>().OrderByDescending(a => a.Id).Limit(1000).ToList();
g.mysql.Update<TopicBulk>().SetSource(items).ExecuteMySqlBulkCopy();
g.mysql.Update<TopicBulk>().SetSource(items, a => new { a.Id, a.Clicks }).ExecuteMySqlBulkCopy();
g.mysql.Update<TopicBulk>().SetSource(items).UpdateColumns(a => new { a.Title }).ExecuteMySqlBulkCopy();
g.mysql.Update<TopicBulk>().SetSource(items, a => new { a.Id, a.Clicks }).UpdateColumns(a => new { a.Title }).ExecuteMySqlBulkCopy();
}
[Fact] [Fact]
public void AsTable() public void AsTable()
{ {

View File

@ -8,7 +8,7 @@ public class g
{ {
static Lazy<IFreeSql> mysqlLazy = new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder() static Lazy<IFreeSql> mysqlLazy = new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10;AllowLoadLocalInfile=true") .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10;AllowLoadLocalInfile=true;AllowZeroDateTime=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_mysqlconnector;Charset=utf8;SslMode=none;")) //.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_mysqlconnector;Charset=utf8;SslMode=none;"))
//.UseConnectionString(FreeSql.DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10")
.UseAutoSyncStructure(true) .UseAutoSyncStructure(true)

View File

@ -4,6 +4,126 @@
<name>FreeSql.Tests</name> <name>FreeSql.Tests</name>
</assembly> </assembly>
<members> <members>
<member name="T:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01">
<summary>
实时数据
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.Guid">
<summary>
Guid
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.TenantId">
<summary>
租户Id
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.Version">
<summary>
版本
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.IsDeleted">
<summary>
是否删除
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.CreatedUserId">
<summary>
创建者Id
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.CreatedUserNameUpdate01">
<summary>
创建者
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.CreatedTime">
<summary>
创建时间
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.ModifiedUserId">
<summary>
修改者Id
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.ModifiedUserName">
<summary>
修改者
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.ModifiedTime">
<summary>
修改时间
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.DataFlag">
<summary>
数据标识
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.Id">
<summary>
主键Id
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.EquipmentCode">
<summary>
设备编号
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.PropertyCode">
<summary>
数据编号,如为空使用默认数据
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.PropertyName">
<summary>
数据名称,如为空使用默认数据
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.IsValueOrStateChanged">
<summary>
数值或状态是否变更
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.NumericValue">
<summary>
采集数值
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.Remark">
<summary>
备注
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.ServiceFlag">
<summary>
服务标记
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.StrState">
<summary>
状态
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.StrValue">
<summary>
文本数值
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.UnitStr">
<summary>
单位
</summary>
</member>
<member name="P:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01.CollectTime">
<summary>
采集时间
</summary>
</member>
<member name="P:FreeSql.Tests.Firebird.FirebirdCodeFirstTest.AddUniquesInfo.id"> <member name="P:FreeSql.Tests.Firebird.FirebirdCodeFirstTest.AddUniquesInfo.id">
<summary> <summary>
编号 编号

View File

@ -1,4 +1,4 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -137,6 +137,23 @@ namespace FreeSql.Tests.PostgreSQL
insert.AppendData(items.First()).ExecuteInserted(); insert.AppendData(items.First()).ExecuteInserted();
} }
[Fact]
public void ExecutePgCopy()
{
var maxId = g.pgsql.Select<Topic>().Max(a => a.Id);
var items = new List<Topic>();
for (var a = 0; a < 10; a++) items.Add(new Topic { Id = maxId + a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
insert.AppendData(items).InsertIdentity().ExecutePgCopy();
items = g.pgsql.Select<Topic>().OrderByDescending(a => a.Id).Limit(1000).ToList();
var sql = g.pgsql.Insert(items).InsertIdentity().NoneParameter().ToSql();
g.pgsql.Update<Topic>().SetSource(items).ExecutePgCopy();
g.pgsql.Update<Topic>().SetSource(items, a => new { a.Id, a.Clicks }).ExecutePgCopy();
g.pgsql.Update<Topic>().SetSource(items).UpdateColumns(a => new { a.Title }).ExecutePgCopy();
g.pgsql.Update<Topic>().SetSource(items, a => new { a.Id, a.Clicks }).UpdateColumns(a => new { a.Title }).ExecutePgCopy();
}
[Fact] [Fact]
public void AsTable() public void AsTable()
{ {

View File

@ -227,12 +227,19 @@ namespace FreeSql.Tests.SqlServer
[Fact] [Fact]
public void ExecuteSqlBulkCopy() public void ExecuteSqlBulkCopy()
{ {
var maxId = g.pgsql.Select<Topic>().Max(a => a.Id);
var items = new List<Topic>(); var items = new List<Topic>();
for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = maxId + a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
insert.AppendData(items).InsertIdentity().ExecuteSqlBulkCopy(); insert.AppendData(items).InsertIdentity().ExecuteSqlBulkCopy();
//insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.Clicks }).ExecuteSqlBulkCopy(); //insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.Clicks }).ExecuteSqlBulkCopy();
// System.NotSupportedException:“DataSet does not support System.Nullable<>.” // System.NotSupportedException:“DataSet does not support System.Nullable<>.”
items = g.sqlserver.Select<Topic>().OrderByDescending(a => a.Id).Limit(1000).ToList();
g.sqlserver.Update<Topic>().SetSource(items).ExecuteSqlBulkCopy();
g.sqlserver.Update<Topic>().SetSource(items, a => new { a.Id, a.TypeGuid }).ExecuteSqlBulkCopy();
g.sqlserver.Update<Topic>().SetSource(items).UpdateColumns(a => new { a.Title }).ExecuteSqlBulkCopy();
g.sqlserver.Update<Topic>().SetSource(items, a => new { a.Id, a.TypeGuid }).UpdateColumns(a => new { a.Title }).ExecuteSqlBulkCopy();
} }
[Fact] [Fact]

View File

@ -25,6 +25,7 @@ namespace FreeSql.Internal.CommonProvider
public DbConnection _connection; public DbConnection _connection;
public int _commandTimeout = 0; public int _commandTimeout = 0;
public Action<StringBuilder> _interceptSql; public Action<StringBuilder> _interceptSql;
public bool _isAutoSyncStructure;
} }
public abstract partial class DeleteProvider<T1> : DeleteProvider, IDelete<T1> public abstract partial class DeleteProvider<T1> : DeleteProvider, IDelete<T1>
@ -35,8 +36,9 @@ namespace FreeSql.Internal.CommonProvider
_commonUtils = commonUtils; _commonUtils = commonUtils;
_commonExpression = commonExpression; _commonExpression = commonExpression;
_table = _commonUtils.GetTableByEntity(typeof(T1)); _table = _commonUtils.GetTableByEntity(typeof(T1));
_isAutoSyncStructure = _orm.CodeFirst.IsAutoSyncStructure;
this.Where(_commonUtils.WhereObject(_table, "", dywhere)); this.Where(_commonUtils.WhereObject(_table, "", dywhere));
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>(); if (_isAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
_whereGlobalFilter = _orm.GlobalFilter.GetFilters(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters();
} }
@ -145,7 +147,7 @@ namespace FreeSql.Internal.CommonProvider
if (string.IsNullOrEmpty(newname)) return _table.DbName; if (string.IsNullOrEmpty(newname)) return _table.DbName;
if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname);
return newname; return newname;
} }
public IDelete<T1> AsTable(Func<string, string> tableRule) public IDelete<T1> AsTable(Func<string, string> tableRule)
@ -164,7 +166,7 @@ namespace FreeSql.Internal.CommonProvider
if (entityType == _table.Type) return this; if (entityType == _table.Type) return this;
var newtb = _commonUtils.GetTableByEntity(entityType); var newtb = _commonUtils.GetTableByEntity(entityType);
_table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IDelete")); _table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IDelete"));
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
return this; return this;
} }

View File

@ -31,6 +31,7 @@ namespace FreeSql.Internal.CommonProvider
public DbTransaction _transaction; public DbTransaction _transaction;
public DbConnection _connection; public DbConnection _connection;
public int _commandTimeout = 0; public int _commandTimeout = 0;
public bool _isAutoSyncStructure;
} }
public abstract partial class InsertProvider<T1> : InsertProvider, IInsert<T1> where T1 : class public abstract partial class InsertProvider<T1> : InsertProvider, IInsert<T1> where T1 : class
@ -46,7 +47,8 @@ namespace FreeSql.Internal.CommonProvider
_commonExpression = commonExpression; _commonExpression = commonExpression;
_table = _commonUtils.GetTableByEntity(typeof(T1)); _table = _commonUtils.GetTableByEntity(typeof(T1));
_noneParameter = _orm.CodeFirst.IsNoneCommandParameter; _noneParameter = _orm.CodeFirst.IsNoneCommandParameter;
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>(); _isAutoSyncStructure = _orm.CodeFirst.IsAutoSyncStructure;
if (_isAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
IgnoreCanInsert(); IgnoreCanInsert();
_sourceOld = _source; _sourceOld = _source;
} }
@ -568,7 +570,7 @@ namespace FreeSql.Internal.CommonProvider
if (string.IsNullOrEmpty(newname)) return tbname; if (string.IsNullOrEmpty(newname)) return tbname;
if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table?.Type, newname); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table?.Type, newname);
return newname; return newname;
} }
public IInsert<T1> AsTable(Func<string, string> tableRule) public IInsert<T1> AsTable(Func<string, string> tableRule)
@ -588,7 +590,7 @@ namespace FreeSql.Internal.CommonProvider
if (entityType == _table.Type) return this; if (entityType == _table.Type) return this;
var newtb = _commonUtils.GetTableByEntity(entityType); var newtb = _commonUtils.GetTableByEntity(entityType);
_table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IInsert")); _table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IInsert"));
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
IgnoreCanInsert(); IgnoreCanInsert();
return this; return this;
} }

View File

@ -38,9 +38,10 @@ namespace FreeSql.Internal.CommonProvider
public int _commandTimeout = 0; public int _commandTimeout = 0;
public Action<StringBuilder> _interceptSql; public Action<StringBuilder> _interceptSql;
public object _updateVersionValue; public object _updateVersionValue;
public bool _isAutoSyncStructure;
public static int ExecuteBulkUpdate<T1>(UpdateProvider<T1> update, NativeTuple<string, string, string, string> state, Action<IInsert<T1>> funcBulkCopy) where T1 : class public static int ExecuteBulkUpdate<T1>(UpdateProvider<T1> update, NativeTuple<string, string, string, string, string[]> state, Action<IInsert<T1>> funcBulkCopy) where T1 : class
{ {
if (update._source.Any() != true || update._tempPrimarys.Any() == false) return 0; if (update._source.Any() != true || update._tempPrimarys.Any() == false) return 0;
var fsql = update._orm; var fsql = update._orm;
@ -59,12 +60,16 @@ namespace FreeSql.Internal.CommonProvider
fsql.Ado.CommandFluent(state.Item1).WithConnection(connection).WithTransaction(transaction).ExecuteNonQuery(); fsql.Ado.CommandFluent(state.Item1).WithConnection(connection).WithTransaction(transaction).ExecuteNonQuery();
try try
{ {
funcBulkCopy(fsql.Insert<T1>(update._source) var insert = fsql.Insert<T1>(update._source)
.AsType(update._table.Type) .AsType(update._table.Type)
.WithConnection(connection) .WithConnection(connection)
.WithTransaction(transaction) .WithTransaction(transaction)
.InsertIdentity().AsTable(state.Item4)); .InsertIdentity()
var affrows = fsql.Ado.CommandFluent(state.Item2 + ";" + state.Item3).WithConnection(connection).WithTransaction(transaction).ExecuteNonQuery(); .InsertColumns(state.Item5)
.AsTable(state.Item4);
(insert as InsertProvider)._isAutoSyncStructure = false;
funcBulkCopy(insert);
var affrows = fsql.Ado.CommandFluent(state.Item2 + ";\r\n" + state.Item3).WithConnection(connection).WithTransaction(transaction).ExecuteNonQuery();
droped = true; droped = true;
return affrows; return affrows;
} }
@ -80,7 +85,7 @@ namespace FreeSql.Internal.CommonProvider
} }
#if net40 #if net40
#else #else
async public static Task<int> ExecuteBulkUpdateAsync<T1>(UpdateProvider<T1> update, NativeTuple<string, string, string, string> state, Func<IInsert<T1>, Task> funcBulkCopy) where T1 : class async public static Task<int> ExecuteBulkUpdateAsync<T1>(UpdateProvider<T1> update, NativeTuple<string, string, string, string, string[]> state, Func<IInsert<T1>, Task> funcBulkCopy) where T1 : class
{ {
if (update._source.Any() != true || update._tempPrimarys.Any() == false) return 0; if (update._source.Any() != true || update._tempPrimarys.Any() == false) return 0;
var fsql = update._orm; var fsql = update._orm;
@ -99,12 +104,16 @@ namespace FreeSql.Internal.CommonProvider
await fsql.Ado.CommandFluent(state.Item1).WithConnection(connection).WithTransaction(transaction).ExecuteNonQueryAsync(); await fsql.Ado.CommandFluent(state.Item1).WithConnection(connection).WithTransaction(transaction).ExecuteNonQueryAsync();
try try
{ {
await funcBulkCopy(fsql.Insert<T1>(update._source) var insert = fsql.Insert<T1>(update._source)
.AsType(update._table.Type) .AsType(update._table.Type)
.WithConnection(connection) .WithConnection(connection)
.WithTransaction(transaction) .WithTransaction(transaction)
.InsertIdentity().AsTable(state.Item4)); .InsertIdentity()
var affrows = await fsql.Ado.CommandFluent(state.Item2 + ";" + state.Item3).WithConnection(connection).WithTransaction(transaction).ExecuteNonQueryAsync(); .InsertColumns(state.Item5)
.AsTable(state.Item4);
(insert as InsertProvider)._isAutoSyncStructure = false;
await funcBulkCopy(insert);
var affrows = await fsql.Ado.CommandFluent(state.Item2 + ";\r\n" + state.Item3).WithConnection(connection).WithTransaction(transaction).ExecuteNonQueryAsync();
droped = true; droped = true;
return affrows; return affrows;
} }
@ -136,8 +145,9 @@ namespace FreeSql.Internal.CommonProvider
_tempPrimarys = _table?.Primarys ?? new ColumnInfo[0]; _tempPrimarys = _table?.Primarys ?? new ColumnInfo[0];
_versionColumn = _table?.VersionColumn; _versionColumn = _table?.VersionColumn;
_noneParameter = _orm.CodeFirst.IsNoneCommandParameter; _noneParameter = _orm.CodeFirst.IsNoneCommandParameter;
_isAutoSyncStructure = _orm.CodeFirst.IsAutoSyncStructure;
this.Where(_commonUtils.WhereObject(_table, "", dywhere)); this.Where(_commonUtils.WhereObject(_table, "", dywhere));
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>(); if (_isAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
IgnoreCanUpdate(); IgnoreCanUpdate();
_whereGlobalFilter = _orm.GlobalFilter.GetFilters(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters();
_sourceOld = _source; _sourceOld = _source;
@ -879,7 +889,7 @@ namespace FreeSql.Internal.CommonProvider
if (string.IsNullOrEmpty(newname)) return _table.DbName; if (string.IsNullOrEmpty(newname)) return _table.DbName;
if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname);
return newname; return newname;
} }
public IUpdate<T1> AsTable(Func<string, string> tableRule) public IUpdate<T1> AsTable(Func<string, string> tableRule)
@ -900,7 +910,7 @@ namespace FreeSql.Internal.CommonProvider
_table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IUpdate")); _table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IUpdate"));
_tempPrimarys = _table.Primarys; _tempPrimarys = _table.Primarys;
_versionColumn = _ignoreVersion ? null : _table.VersionColumn; _versionColumn = _ignoreVersion ? null : _table.VersionColumn;
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
IgnoreCanUpdate(); IgnoreCanUpdate();
return this; return this;
} }

View File

@ -34,60 +34,37 @@ public static class FreeSqlMySqlConnectorGlobalExtensions
var state = ExecuteMySqlBulkCopyState(update); var state = ExecuteMySqlBulkCopyState(update);
return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecuteMySqlBulkCopy(bulkCopyTimeout)); return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecuteMySqlBulkCopy(bulkCopyTimeout));
} }
static NativeTuple<string, string, string, string> ExecuteMySqlBulkCopyState<T>(UpdateProvider<T> update) where T : class static NativeTuple<string, string, string, string, string[]> ExecuteMySqlBulkCopyState<T>(UpdateProvider<T> update) where T : class
{ {
if (update._source.Any() != true) return null; if (update._source.Any() != true) return null;
var _table = update._table; var _table = update._table;
var _tempPrimarys = update._tempPrimarys;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var _ignore = update._ignore;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}";
if (update._connection == null) if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)
update.WithTransaction(update._orm.Ado.TransactionCurrentThread);
var sb = new StringBuilder().Append("CREATE TEMPORARY TABLE ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" ( ");
var setColumns = new List<string>();
var pkColumns = new List<string>();
foreach (var col in _table.Columns.Values)
{ {
if (update._orm.Ado.TransactionCurrentThread != null) if (update._tempPrimarys.Any(a => a.CsName == col.CsName)) pkColumns.Add(col.Attribute.Name);
update.WithTransaction(update._orm.Ado.TransactionCurrentThread); else if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && update._ignore.ContainsKey(col.Attribute.Name) == false) setColumns.Add(col.Attribute.Name);
} else continue;
var sb = new StringBuilder(); sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" ").Append(col.Attribute.DbType.Replace("NOT NULL", ""));
sb.Append("CREATE TEMPORARY TABLE ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" ( ");
foreach (var tbcol in _table.ColumnsByPosition)
{
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
sb.Append(","); sb.Append(",");
} }
//if (_tempPrimarys.Any())
//{
// sb.Append(" \r\n PRIMARY KEY (");
// foreach (var tbcol in _tempPrimarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
// sb.Remove(sb.Length - 2, 2).Append("),");
//}
var sql1 = sb.Remove(sb.Length - 1, 1).Append(" \r\n) Engine=InnoDB;").ToString(); var sql1 = sb.Remove(sb.Length - 1, 1).Append(" \r\n) Engine=InnoDB;").ToString();
sb.Clear().Append("UPDATE ").Append(_commonUtils.QuoteSqlName(updateTableName)).Append(" a ") sb.Clear().Append("UPDATE ").Append(_commonUtils.QuoteSqlName(updateTableName)).Append(" a ")
.Append(" \r\nINNER JOIN ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" b ON "); .Append(" \r\nINNER JOIN ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" b ON ").Append(string.Join(" AND ", pkColumns.Select(col => $"a.{_commonUtils.QuoteSqlName(col)} = b.{_commonUtils.QuoteSqlName(col)}")))
for (var a = 0; a < _tempPrimarys.Length; a++) .Append(" \r\nSET \r\n ").Append(string.Join(", \r\n ", setColumns.Select(col => $"a.{_commonUtils.QuoteSqlName(col)} = b.{_commonUtils.QuoteSqlName(col)}")));
{
var pkname = _commonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name);
if (a > 0) sb.Append(" AND ");
sb.Append("b.").Append(pkname).Append(" = a.").Append(pkname);
}
sb.Append("\r\n SET ");
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (col.Attribute.IsPrimary) continue;
if (_tempPrimarys.Any(a => a.CsName == col.CsName)) continue;
if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false)
{
if (colidx > 0) sb.Append(",");
sb.Append(" \r\n a.").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append("b.").Append(_commonUtils.QuoteSqlName(col.Attribute.Name));
++colidx;
}
}
var sql2 = sb.ToString(); var sql2 = sb.ToString();
sb.Clear(); sb.Clear();
var sql3 = $"DROP TABLE {_commonUtils.QuoteSqlName(tempTableName)}"; var sql3 = $"DROP TABLE {_commonUtils.QuoteSqlName(tempTableName)}";
return NativeTuple.Create(sql1, sql2, sql3, tempTableName); return NativeTuple.Create(sql1, sql2, sql3, tempTableName, pkColumns.Concat(setColumns).ToArray());
} }
/// <summary> /// <summary>

View File

@ -4,6 +4,7 @@ using FreeSql.Internal.Model;
using FreeSql.PostgreSQL.Curd; using FreeSql.PostgreSQL.Curd;
using Npgsql; using Npgsql;
using System; using System;
using System.Collections.Generic;
using System.Data; using System.Data;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -49,53 +50,38 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions
var state = ExecutePgCopyState(update); var state = ExecutePgCopyState(update);
return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecutePgCopy()); return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecutePgCopy());
} }
static NativeTuple<string, string, string, string> ExecutePgCopyState<T>(UpdateProvider<T> update) where T : class static NativeTuple<string, string, string, string, string[]> ExecutePgCopyState<T>(UpdateProvider<T> update) where T : class
{ {
if (update._source.Any() != true) return null; if (update._source.Any() != true) return null;
var _table = update._table; var _table = update._table;
var _tempPrimarys = update._tempPrimarys;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var _ignore = update._ignore;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}";
if (update._connection == null) if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)
update.WithTransaction(update._orm.Ado.TransactionCurrentThread);
var sb = new StringBuilder().Append("CREATE TEMP TABLE ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" ( ");
var setColumns = new List<string>();
var pkColumns = new List<string>();
foreach (var col in _table.Columns.Values)
{ {
if (update._orm.Ado.TransactionCurrentThread != null) if (update._tempPrimarys.Any(a => a.CsName == col.CsName)) pkColumns.Add(col.Attribute.Name);
update.WithTransaction(update._orm.Ado.TransactionCurrentThread); else if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && update._ignore.ContainsKey(col.Attribute.Name) == false) setColumns.Add(col.Attribute.Name);
} else continue;
var sb = new StringBuilder(); sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" ").Append(col.Attribute.DbType.Replace("NOT NULL", ""));
sb.Append("CREATE TEMP TABLE ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" ( ");
foreach (var tbcol in _table.ColumnsByPosition)
{
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
sb.Append(","); sb.Append(",");
} }
var sql1 = sb.Remove(sb.Length - 1, 1).Append("\r\n) WITH (OIDS=FALSE);").ToString(); var sql1 = sb.Remove(sb.Length - 1, 1).Append("\r\n) WITH (OIDS=FALSE);").ToString();
sb.Clear().Append("UPDATE ").Append(_commonUtils.QuoteSqlName(updateTableName)).Append(" a \r\nSET "); sb.Clear().Append("UPDATE ").Append(_commonUtils.QuoteSqlName(updateTableName)).Append(" a ")
var colidx = 0; .Append("\r\nSET \r\n ").Append(string.Join(", \r\n ", setColumns.Select(col => $"{_commonUtils.QuoteSqlName(col)} = b.{_commonUtils.QuoteSqlName(col)}")))
foreach (var col in _table.Columns.Values) .Append("\r\nFROM ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" b ")
{ .Append("\r\nWHERE ").Append(string.Join(" AND ", pkColumns.Select(col => $"a.{_commonUtils.QuoteSqlName(col)} = b.{_commonUtils.QuoteSqlName(col)}")));
if (col.Attribute.IsPrimary) continue;
if (_tempPrimarys.Any(a => a.CsName == col.CsName)) continue;
if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false)
{
if (colidx > 0) sb.Append(",");
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append("b.").Append(_commonUtils.QuoteSqlName(col.Attribute.Name));
++colidx;
}
}
sb.Append(" \r\nFROM ").Append(_commonUtils.QuoteSqlName(tempTableName)).Append(" b \r\nWHERE ");
for (var a = 0; a < _tempPrimarys.Length; a++)
{
var pkname = _commonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name);
if (a > 0) sb.Append(" AND ");
sb.Append("b.").Append(pkname).Append(" = a.").Append(pkname);
}
var sql2 = sb.ToString(); var sql2 = sb.ToString();
sb.Clear(); sb.Clear();
var sql3 = $"DROP TABLE {_commonUtils.QuoteSqlName(tempTableName)}"; var sql3 = $"DROP TABLE {_commonUtils.QuoteSqlName(tempTableName)}";
return NativeTuple.Create(sql1, sql2, sql3, tempTableName); return NativeTuple.Create(sql1, sql2, sql3, tempTableName, pkColumns.Concat(setColumns).ToArray());
} }
/// <summary> /// <summary>

View File

@ -136,46 +136,32 @@ public static partial class FreeSqlSqlServerGlobalExtensions
var state = ExecuteSqlBulkCopyState(update); var state = ExecuteSqlBulkCopyState(update);
return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecuteSqlBulkCopy(copyOptions, batchSize, bulkCopyTimeout)); return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecuteSqlBulkCopy(copyOptions, batchSize, bulkCopyTimeout));
} }
static NativeTuple<string, string, string, string> ExecuteSqlBulkCopyState<T>(UpdateProvider<T> update) where T : class static NativeTuple<string, string, string, string, string[]> ExecuteSqlBulkCopyState<T>(UpdateProvider<T> update) where T : class
{ {
if (update._source.Any() != true) return null; if (update._source.Any() != true) return null;
var _table = update._table; var _table = update._table;
var _tempPrimarys = update._tempPrimarys;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var _ignore = update._ignore;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"#Temp_{updateTableName}"; var tempTableName = $"#Temp_{updateTableName}";
if (update._connection == null) if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
{ if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._orm.Ado.TransactionCurrentThread != null) if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)
update.WithTransaction(update._orm.Ado.TransactionCurrentThread); update.WithTransaction(update._orm.Ado.TransactionCurrentThread);
} var setColumns = new List<string>();
var sql1 = $"SELECT * INTO {tempTableName} FROM {_commonUtils.QuoteSqlName(updateTableName)} WHERE 1=2"; var pkColumns = new List<string>();
var sb = new StringBuilder().Append("UPDATE ").Append(" a SET \r\n ");
var colidx = 0;
foreach (var col in _table.Columns.Values) foreach (var col in _table.Columns.Values)
{ {
if (col.Attribute.IsPrimary) continue; if (update._tempPrimarys.Any(a => a.CsName == col.CsName)) pkColumns.Add(col.Attribute.Name);
if (_tempPrimarys.Any(a => a.CsName == col.CsName)) continue; else if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && update._ignore.ContainsKey(col.Attribute.Name) == false) setColumns.Add(col.Attribute.Name);
if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false)
{
if (colidx > 0) sb.Append(", \r\n ");
sb.Append(" a.").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append("b.").Append(_commonUtils.QuoteSqlName(col.Attribute.Name));
++colidx;
}
} }
var sql1 = $"SELECT {string.Join(", ", pkColumns)}, {string.Join(", ", setColumns)} INTO {tempTableName} FROM {_commonUtils.QuoteSqlName(updateTableName)} WHERE 1=2";
var sb = new StringBuilder().Append("UPDATE ").Append(" a SET \r\n ").Append(string.Join(", \r\n ", setColumns.Select(col => $"a.{_commonUtils.QuoteSqlName(col)} = b.{_commonUtils.QuoteSqlName(col)}")));
sb.Append(" \r\nFROM ").Append(_commonUtils.QuoteSqlName(updateTableName)).Append(" a ") sb.Append(" \r\nFROM ").Append(_commonUtils.QuoteSqlName(updateTableName)).Append(" a ")
.Append(" \r\nINNER JOIN ").Append(tempTableName).Append(" b ON "); .Append(" \r\nINNER JOIN ").Append(tempTableName).Append(" b ON ").Append(string.Join(" AND ", pkColumns.Select(col => $"a.{_commonUtils.QuoteSqlName(col)} = b.{_commonUtils.QuoteSqlName(col)}")));
for (var a = 0; a < _tempPrimarys.Length; a++)
{
var pkname = _commonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name);
if (a > 0) sb.Append(" AND ");
sb.Append("b.").Append(pkname).Append(" = a.").Append(pkname);
}
var sql2 = sb.ToString(); var sql2 = sb.ToString();
sb.Clear(); sb.Clear();
var sql3 = $"DROP TABLE {tempTableName}"; var sql3 = $"DROP TABLE {tempTableName}";
return NativeTuple.Create(sql1, sql2, sql3, tempTableName); return NativeTuple.Create(sql1, sql2, sql3, tempTableName, pkColumns.Concat(setColumns).ToArray());
} }
/// <summary> /// <summary>