From 1e23938e4e7868455aea1115e5e30c7cd9f968b1 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 29 Mar 2023 19:07:19 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20SqlServer=20=E8=87=AA?= =?UTF-8?q?=E5=A2=9E=20BulkUpdate=20bug=EF=BC=9B#1476?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Entities/User.cs | 10 +++++ Examples/base_entity/ModAsTableImpl.cs | 45 +++++++++++++++++++ Examples/base_entity/Program.cs | 30 ++++++++++--- FreeSql.DbContext/FreeSql.DbContext.xml | 18 ++++++++ .../SqlServerExtensions.cs | 8 ++-- 5 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 Examples/base_entity/ModAsTableImpl.cs diff --git a/Examples/base_entity/Entities/User.cs b/Examples/base_entity/Entities/User.cs index 70982857..457f0d6e 100644 --- a/Examples/base_entity/Entities/User.cs +++ b/Examples/base_entity/Entities/User.cs @@ -27,6 +27,16 @@ public class RoleUser1 : BaseEntity public User1 User1 { get; set; } } +public class IdentityUser1 +{ + [Column(IsIdentity = true)] + public int Id { get; set; } + [MaxLength(32)] + public string Username { get; set; } + [MaxLength(64)] + public string Nickname { get; set; } +} + public class User1 : BaseEntity { public int GroupId { get; set; } diff --git a/Examples/base_entity/ModAsTableImpl.cs b/Examples/base_entity/ModAsTableImpl.cs new file mode 100644 index 00000000..3c802b21 --- /dev/null +++ b/Examples/base_entity/ModAsTableImpl.cs @@ -0,0 +1,45 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +class ModAsTableImpl : IAsTable +{ + public ModAsTableImpl(IFreeSql fsql) + { + AllTables = Enumerable.Range(0, 9).Select(a => $"order_{a}").ToArray(); + fsql.Aop.CommandBefore += (_, e) => + { + e.Command.CommandText = Regex.Replace(e.Command.CommandText, @"/\*astable\([^\)]+\)*\/", "1=1"); + }; + } + + public string[] AllTables { get; } + + public string GetTableNameByColumnValue(object columnValue, bool autoExpand = false) + { + var modid = (int)columnValue; + return $"order_{(modid % 10)}"; + } + + public string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2) + { + throw new NotImplementedException(); + } + + public string[] GetTableNamesBySqlWhere(string sqlWhere, List dbParams, SelectTableInfo tb, CommonUtils commonUtils) + { + var match = Regex.Match(sqlWhere, @"/\*astable\([^\)]+\)*\/"); + if (match.Success == false) return AllTables; + var tables = match.Groups[1].Value.Split(',').Where(a => AllTables.Contains(a)).ToArray(); + if (tables.Any() == false) return AllTables; + return tables; + } +} diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 990204a6..386c04bf 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -6,6 +6,7 @@ using FreeSql.Internal; using FreeSql.Internal.CommonProvider; using FreeSql.Internal.Model; using FreeSql.Odbc.Default; +using Microsoft.Data.SqlClient; using NetTopologySuite.Geometries; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -541,7 +542,7 @@ namespace base_entity .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=2;AllowLoadLocalInfile=true") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=toc;Pooling=true;Maximum Pool Size=2") @@ -576,6 +577,23 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + var bulkUsers = new[] { + new IdentityUser1 { Nickname = "nickname11", Username = "username11" }, + new IdentityUser1 { Nickname = "nickname12", Username = "username12" }, + new IdentityUser1 { Nickname = "nickname13", Username = "username13" }, + + new IdentityUser1 { Nickname = "nickname21", Username = "username21" }, + new IdentityUser1 { Nickname = "nickname22", Username = "username22" }, + new IdentityUser1 { Nickname = "nickname23", Username = "username23" } + }; + fsql.Insert(bulkUsers).NoneParameter().ExecuteAffrows(); + bulkUsers = fsql.Select().OrderByDescending(a => a.Id).Limit(3).ToList().ToArray(); + bulkUsers[0].Nickname += "_bulkupdate"; + bulkUsers[1].Nickname += "_bulkupdate"; + bulkUsers[2].Nickname += "_bulkupdate"; + fsql.Update().SetSource(bulkUsers).ExecuteSqlBulkCopy(); + + var objtsql1 = fsql.Select().WithSql("select * from user1").ToList(); var objtsql2 = fsql.Select().WithSql("select * from user1").ToList(); @@ -585,8 +603,8 @@ namespace base_entity .ToSql(); - var table = fsql.CodeFirst.GetTableByEntity(typeof(AsTableLog)); - //table.SetAsTable(null, table.ColumnsByCs[nameof(AsTableLog.createtime)]); + //var table = fsql.CodeFirst.GetTableByEntity(typeof(AsTableLog)); + //table.SetAsTable(new ModAsTableImpl(fsql), table.ColumnsByCs[nameof(AsTableLog.click)]); var testitems = new[] @@ -598,9 +616,9 @@ namespace base_entity new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13"), click = 5 }, new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13"), click = 6 }, new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13"), click = 7 }, - new AsTableLog{ msg = "msg08", createtime = DateTime.Parse("2022-7-1"), click = 8}, - new AsTableLog{ msg = "msg09", createtime = DateTime.Parse("2022-7-1 11:00:00"), click = 8} - + new AsTableLog{ msg = "msg08", createtime = DateTime.Parse("2022-7-1"), click = 9}, + new AsTableLog{ msg = "msg09", createtime = DateTime.Parse("2022-7-1 11:00:00"), click = 10}, + new AsTableLog{ msg = "msg10", createtime = DateTime.Parse("2022-7-1 12:00:00"), click = 10} }; var sqlatb = fsql.Insert(testitems).NoneParameter(); var sqlat = sqlatb.ToSql(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 594fbad3..26522f10 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -733,6 +733,15 @@ + + + 根据Assembly扫描所有继承IEntityTypeConfiguration<T>的配置类 + + + + + + 创建普通数据上下文档对象 @@ -791,5 +800,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index ef79c803..86e2a23d 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -134,7 +134,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions var upsert = that as InsertOrUpdateProvider; if (upsert._source.Any() != true || upsert._tempPrimarys.Any() == false) return 0; var state = ExecuteSqlBulkCopyState(upsert); - return UpdateProvider.ExecuteBulkUpsert(upsert, state, insert => insert.ExecuteSqlBulkCopy(copyOptions, batchSize, bulkCopyTimeout)); + return UpdateProvider.ExecuteBulkUpsert(upsert, state, insert => insert.ExecuteSqlBulkCopy(copyOptions | SqlBulkCopyOptions.KeepIdentity, batchSize, bulkCopyTimeout)); } static NativeTuple ExecuteSqlBulkCopyState(InsertOrUpdateProvider upsert) where T : class { @@ -175,7 +175,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions var update = that as UpdateProvider; if (update._source.Any() != true || update._tempPrimarys.Any() == false) return 0; var state = ExecuteSqlBulkCopyState(update); - return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecuteSqlBulkCopy(copyOptions, batchSize, bulkCopyTimeout)); + return UpdateProvider.ExecuteBulkUpdate(update, state, insert => insert.ExecuteSqlBulkCopy(copyOptions | SqlBulkCopyOptions.KeepIdentity, batchSize, bulkCopyTimeout)); } static NativeTuple ExecuteSqlBulkCopyState(UpdateProvider update) where T : class { @@ -309,14 +309,14 @@ public static partial class FreeSqlSqlServerGlobalExtensions var upsert = that as InsertOrUpdateProvider; if (upsert._source.Any() != true || upsert._tempPrimarys.Any() == false) return Task.FromResult(0); var state = ExecuteSqlBulkCopyState(upsert); - return UpdateProvider.ExecuteBulkUpsertAsync(upsert, state, insert => insert.ExecuteSqlBulkCopyAsync(copyOptions, batchSize, bulkCopyTimeout, cancellationToken)); + return UpdateProvider.ExecuteBulkUpsertAsync(upsert, state, insert => insert.ExecuteSqlBulkCopyAsync(copyOptions | SqlBulkCopyOptions.KeepIdentity, batchSize, bulkCopyTimeout, cancellationToken)); } public static Task ExecuteSqlBulkCopyAsync(this IUpdate that, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null, CancellationToken cancellationToken = default) where T : class { var update = that as UpdateProvider; if (update._source.Any() != true || update._tempPrimarys.Any() == false) return Task.FromResult(0); var state = ExecuteSqlBulkCopyState(update); - return UpdateProvider.ExecuteBulkUpdateAsync(update, state, insert => insert.ExecuteSqlBulkCopyAsync(copyOptions, batchSize, bulkCopyTimeout, cancellationToken)); + return UpdateProvider.ExecuteBulkUpdateAsync(update, state, insert => insert.ExecuteSqlBulkCopyAsync(copyOptions | SqlBulkCopyOptions.KeepIdentity, batchSize, bulkCopyTimeout, cancellationToken)); } async public static Task ExecuteSqlBulkCopyAsync(this IInsert that, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null, CancellationToken cancellationToken = default) where T : class {