mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 完善 BulkCopy Update
This commit is contained in:
parent
768b715e18
commit
09864eaa9f
@ -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");
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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>
|
||||||
编号
|
编号
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -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]
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user