diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 6b638cad..1ab5bf1c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -795,5 +795,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs index 9991361c..083c3805 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -373,11 +373,10 @@ WHEN NOT MATCHED THEN } [Fact] - public void InsertOrUpdate_OnColumns() + public void InsertOrUpdate_TempPrimarys() { var iou = fsql.InsertOrUpdate() - .SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }) - .OnColumns("name"); + .SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }, a => a.name); var sql = iou.ToSql(); Assert.Equal(@"MERGE INTO [tbiou03] t1 USING (SELECT 1 as [id1], N'01' as [id2], N'001' as [name] @@ -388,7 +387,7 @@ UNION ALL UNION ALL SELECT 4, N'04', N'004' ) t2 ON (t1.[name] = t2.[name]) WHEN MATCHED THEN - update set [name] = t2.[name] + update set [id1] = t2.[id1], [id2] = t2.[id2] WHEN NOT MATCHED THEN insert ([id1], [id2], [name]) values (t2.[id1], t2.[id2], t2.[name]);", sql); diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 15ba7b51..41db7e4b 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -1112,6 +1112,7 @@ SELECT "); public InsertOrUpdateDictImpl WherePrimary(params string[] primarys) { UpdateDictImpl.SetTablePrimary(_insertOrUpdateProvider._table, primarys); + _insertOrUpdateProvider._tempPrimarys = _insertOrUpdateProvider._table.Primarys; return this; } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index fe98cb90..135f77d3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1778,11 +1778,15 @@ 实体 - + 添加或更新,设置实体集合 实体集合 + + 根据临时主键插入或更新,a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"} + 注意:不处理自增,因某些数据库依赖主键或唯一键,所以指定临时主键仅对 SqlServer/PostgreSQL/Firebird/达梦/南大通用/金仓/神通 有效 + diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs index c2cb1abb..28d9c59d 100644 --- a/FreeSql/Interface/Curd/IInsertOrUpdate.cs +++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs @@ -39,8 +39,12 @@ namespace FreeSql /// 添加或更新,设置实体集合 /// /// 实体集合 + /// + /// 根据临时主键插入或更新,a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"} + /// 注意:不处理自增,因某些数据库依赖主键或唯一键,所以指定临时主键仅对 SqlServer/PostgreSQL/Firebird/达梦/南大通用/金仓/神通 有效 + /// /// - IInsertOrUpdate SetSource(IEnumerable source); + IInsertOrUpdate SetSource(IEnumerable source, Expression> tempPrimarys = null); /// /// 当记录存在时,什么都不做 diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index e1d1378a..fb6efafa 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -14,22 +14,27 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract partial class InsertOrUpdateProvider : IInsertOrUpdate where T1 : class + public abstract partial class InsertOrUpdateProvider { public IFreeSql _orm; public CommonUtils _commonUtils; public CommonExpression _commonExpression; - public List _source = new List(); public bool _doNothing = false; public Dictionary _updateIgnore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public TableInfo _table; + public ColumnInfo[] _tempPrimarys; public Func _tableRule; public DbParameter[] _params; public DbTransaction _transaction; public DbConnection _connection; public int _commandTimeout = 0; - public ColumnInfo IdentityColumn { get; private set; } + public ColumnInfo IdentityColumn { get; protected set; } + } + + public abstract partial class InsertOrUpdateProvider : InsertOrUpdateProvider, IInsertOrUpdate where T1 : class + { + public List _source = new List(); public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { @@ -37,6 +42,7 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _table = _commonUtils.GetTableByEntity(typeof(T1)); + _tempPrimarys = _table?.Primarys ?? new ColumnInfo[0]; if (_table == null && typeof(T1) != typeof(Dictionary)) throw new Exception(CoreStrings.InsertOrUpdate_NotSuport_Generic_UseEntity(typeof(T1))); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); @@ -107,12 +113,18 @@ namespace FreeSql.Internal.CommonProvider } public IInsertOrUpdate SetSource(T1 source) => this.SetSource(new[] { source }); - public IInsertOrUpdate SetSource(IEnumerable source) + public IInsertOrUpdate SetSource(IEnumerable source, Expression> tempPrimarys = null) { if (source == null || source.Any() == false) return this; UpdateProvider.GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table); AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source.Where(a => a != null)); + + if (tempPrimarys != null) + { + var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, null, tempPrimarys?.Body, false, null).Distinct().ToDictionary(a => a); + _tempPrimarys = cols.Keys.Select(a => _table.Columns.TryGetValue(a, out var col) ? col : null).ToArray().Where(a => a != null).ToArray(); + } return this; } @@ -161,6 +173,7 @@ namespace FreeSql.Internal.CommonProvider if (entityType == _table.Type) return this; var newtb = _commonUtils.GetTableByEntity(entityType); _table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IInsertOrUpdate")); + _tempPrimarys = _table.Primarys; if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault(); return this; @@ -221,7 +234,7 @@ namespace FreeSql.Internal.CommonProvider if (source.Any() == false) return NativeTuple.Create(new List[0], new List[0]); if (_SplitSourceByIdentityValueIsNullFlag == 1) return NativeTuple.Create(new[] { source }, new List[0]); if (_SplitSourceByIdentityValueIsNullFlag == 2) return NativeTuple.Create(new List[0], new[] { source }); - if (IdentityColumn == null) return NativeTuple.Create(LocalSplitSourceByAsTable(source), new List[0]); + if (IdentityColumn == null || _tempPrimarys != _table.Primarys) return NativeTuple.Create(LocalSplitSourceByAsTable(source), new List[0]); var item1 = new List(); var item2 = new List(); foreach (var item in source) diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index 48cadbbc..18770e11 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -31,13 +31,13 @@ namespace FreeSql.Dameng.Curd string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs index 83ef5230..abc2fe27 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs @@ -31,13 +31,13 @@ namespace FreeSql.Firebird.Curd string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs index 7b03afdf..e2a5f8aa 100644 --- a/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.GBase/Curd/GBaseInsertOrUpdate.cs @@ -31,13 +31,13 @@ namespace FreeSql.GBase.Curd string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs index a82fbe73..57c25913 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs @@ -43,7 +43,8 @@ namespace FreeSql.KingbaseES else { var ocdu = new KingbaseESOnConflictDoUpdate(insert.InsertIdentity()); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu._tempPrimarys = _tempPrimarys; + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); if (_doNothing == true || cols.Any() == false) ocdu.DoNothing(); diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs index 96b0e538..220b9715 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.KingbaseES internal KingbaseESUpdate _update => _updatePriv ?? (_updatePriv = new KingbaseESUpdate(_insert.InternalOrm, _insert.InternalCommonUtils, _insert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } .NoneParameter().SetSource(_insert.InternalSource) as KingbaseESUpdate); - ColumnInfo[] _columns; + internal ColumnInfo[] _tempPrimarys; bool _doNothing; public KingbaseESOnConflictDoUpdate(IInsert insert, Expression> columns = null) @@ -34,11 +34,11 @@ namespace FreeSql.KingbaseES foreach (var col in _insert.InternalTable.Columns.Values) if (cols.ContainsKey(col.Attribute.Name)) colsList.Add(col); - _columns = colsList.ToArray(); + _tempPrimarys = colsList.ToArray(); } - if (_columns == null || _columns.Any() == false) - _columns = _insert.InternalTable.Primarys; - if (_columns.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); + if (_tempPrimarys == null || _tempPrimarys.Any() == false) + _tempPrimarys = _insert.InternalTable.Primarys; + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); } protected void ClearData() @@ -96,10 +96,10 @@ namespace FreeSql.KingbaseES { var sb = new StringBuilder(); sb.Append(_insert.ToSql()).Append("\r\nON CONFLICT("); - for (var a = 0; a < _columns.Length; a++) + for (var a = 0; a < _tempPrimarys.Length; a++) { if (a > 0) sb.Append(", "); - sb.Append(_insert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + sb.Append(_insert.InternalCommonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name)); } if (_doNothing) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index f779e8fd..f241c994 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -47,14 +47,14 @@ namespace FreeSql.MySql.Curd insert.InsertIdentity(); if (_doNothing == false) { - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); sql = new OnDuplicateKeyUpdate(insert) .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) .ToSql(); } else { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.Entity_Must_Primary_Key("fsql.InsertOrUpdate + IfExistsDoNothing + MySql ", _table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.Entity_Must_Primary_Key("fsql.InsertOrUpdate + IfExistsDoNothing + MySql ", _table.CsName)); sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => sb.Append(" \r\n FROM dual WHERE NOT EXISTS(").Append( _orm.Select() diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index 7863330c..4f74b771 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -31,13 +31,13 @@ namespace FreeSql.Odbc.Dameng string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs index a03500bd..142e8a40 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -45,7 +45,8 @@ namespace FreeSql.Odbc.KingbaseES else { var ocdu = new OdbcKingbaseESOnConflictDoUpdate(insert.InsertIdentity()); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu._tempPrimarys = _tempPrimarys; + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); if (_doNothing == true || cols.Any() == false) ocdu.DoNothing(); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs index ab6fc1c2..dd6f5866 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.Odbc.KingbaseES internal OdbcKingbaseESUpdate _pgsqlUpdate => _pgsqlUpdatePriv ?? (_pgsqlUpdatePriv = new OdbcKingbaseESUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as OdbcKingbaseESUpdate); - ColumnInfo[] _columns; + internal ColumnInfo[] _tempPrimarys; bool _doNothing; public OdbcKingbaseESOnConflictDoUpdate(IInsert insert, Expression> columns = null) @@ -34,11 +34,11 @@ namespace FreeSql.Odbc.KingbaseES foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) if (cols.ContainsKey(col.Attribute.Name)) colsList.Add(col); - _columns = colsList.ToArray(); + _tempPrimarys = colsList.ToArray(); } - if (_columns == null || _columns.Any() == false) - _columns = _pgsqlInsert.InternalTable.Primarys; - if (_columns.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); + if (_tempPrimarys == null || _tempPrimarys.Any() == false) + _tempPrimarys = _pgsqlInsert.InternalTable.Primarys; + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); } protected void ClearData() @@ -96,10 +96,10 @@ namespace FreeSql.Odbc.KingbaseES { var sb = new StringBuilder(); sb.Append(_pgsqlInsert.ToSql()).Append("\r\nON CONFLICT("); - for (var a = 0; a < _columns.Length; a++) + for (var a = 0; a < _tempPrimarys.Length; a++) { if (a > 0) sb.Append(", "); - sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name)); } if (_doNothing) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index 9c904829..0a36859f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -46,14 +46,14 @@ namespace FreeSql.Odbc.MySql insert.InsertIdentity(); if (_doNothing == false) { - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); sql = new OdbcMySqlOnDuplicateKeyUpdate(insert) .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) .ToSql(); } else { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.Entity_Must_Primary_Key("fsql.InsertOrUpdate + IfExistsDoNothing + MySql ", _table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.Entity_Must_Primary_Key("fsql.InsertOrUpdate + IfExistsDoNothing + MySql ", _table.CsName)); sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => sb.Append(" \r\n FROM dual WHERE NOT EXISTS(").Append( _orm.Select() diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index f60feef5..e339a5b5 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -31,13 +31,13 @@ namespace FreeSql.Odbc.Oracle string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index 38ad983c..ca4fe050 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -43,7 +43,8 @@ namespace FreeSql.Odbc.PostgreSQL else { var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert.InsertIdentity()); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu._tempPrimarys = _tempPrimarys; + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); if (_doNothing == true || cols.Any() == false) ocdu.DoNothing(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs index 18adb69a..0e9b42e6 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.Odbc.PostgreSQL internal OdbcPostgreSQLUpdate _pgsqlUpdate => _pgsqlUpdatePriv ?? (_pgsqlUpdatePriv = new OdbcPostgreSQLUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as OdbcPostgreSQLUpdate); - ColumnInfo[] _columns; + internal ColumnInfo[] _tempPrimarys; bool _doNothing; public OdbcPostgreSQLOnConflictDoUpdate(IInsert insert, Expression> columns = null) @@ -34,11 +34,11 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) if (cols.ContainsKey(col.Attribute.Name)) colsList.Add(col); - _columns = colsList.ToArray(); + _tempPrimarys = colsList.ToArray(); } - if (_columns == null || _columns.Any() == false) - _columns = _pgsqlInsert.InternalTable.Primarys; - if (_columns.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); + if (_tempPrimarys == null || _tempPrimarys.Any() == false) + _tempPrimarys = _pgsqlInsert.InternalTable.Primarys; + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); } protected void ClearData() @@ -96,10 +96,10 @@ namespace FreeSql.Odbc.PostgreSQL { var sb = new StringBuilder(); sb.Append(_pgsqlInsert.ToSql()).Append("\r\nON CONFLICT("); - for (var a = 0; a < _columns.Length; a++) + for (var a = 0; a < _tempPrimarys.Length; a++) { if (a > 0) sb.Append(", "); - sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name)); } if (_doNothing) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index df3af8a1..398f1006 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -31,15 +31,15 @@ namespace FreeSql.Odbc.SqlServer string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder(); if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index 43b29199..281af421 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -31,13 +31,13 @@ namespace FreeSql.Oracle.Curd string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index f1ab246c..a0b99260 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.PostgreSQL.Curd internal PostgreSQLUpdate _pgsqlUpdate => _pgsqlUpdatePriv ?? (_pgsqlUpdatePriv = new PostgreSQLUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as PostgreSQLUpdate); - ColumnInfo[] _columns; + internal ColumnInfo[] _tempPrimarys; bool _doNothing; public OnConflictDoUpdate(IInsert insert, Expression> columns = null) @@ -34,11 +34,11 @@ namespace FreeSql.PostgreSQL.Curd foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) if (cols.ContainsKey(col.Attribute.Name)) colsList.Add(col); - _columns = colsList.ToArray(); + _tempPrimarys = colsList.ToArray(); } - if (_columns == null || _columns.Any() == false) - _columns = _pgsqlInsert.InternalTable.Primarys; - if (_columns.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); + if (_tempPrimarys == null || _tempPrimarys.Any() == false) + _tempPrimarys = _pgsqlInsert.InternalTable.Primarys; + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); } protected void ClearData() @@ -96,10 +96,10 @@ namespace FreeSql.PostgreSQL.Curd { var sb = new StringBuilder(); sb.Append(_pgsqlInsert.ToSql()).Append("\r\nON CONFLICT("); - for (var a = 0; a < _columns.Length; a++) + for (var a = 0; a < _tempPrimarys.Length; a++) { if (a > 0) sb.Append(", "); - sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name)); } if (_doNothing) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index 5ca0ff92..bd7c6016 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -43,7 +43,8 @@ namespace FreeSql.PostgreSQL.Curd else { var ocdu = new OnConflictDoUpdate(insert.InsertIdentity()); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu._tempPrimarys = _tempPrimarys; + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); if (_doNothing == true || cols.Any() == false) ocdu.DoNothing(); diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs index 53ab6a47..65ec4076 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -31,13 +31,13 @@ namespace FreeSql.ShenTong.Curd string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index 4d1d7bbe..eca35376 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -10,8 +10,6 @@ namespace FreeSql.SqlServer.Curd class SqlServerInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class { - internal string[] _columns; - public SqlServerInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { @@ -33,20 +31,15 @@ namespace FreeSql.SqlServer.Curd string getMergeSql(List data) { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); var sb = new StringBuilder(); if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); - IEnumerable onColumns; - if (_columns?.Length > 0) - onColumns = _columns.Select(a => $"t1.{_commonUtils.QuoteSqlName(a)} = t2.{_commonUtils.QuoteSqlName(a)}"); - else - onColumns = _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", onColumns)).Append(") \r\n"); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index d13e580c..a2a6dfd7 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -49,25 +49,6 @@ public static partial class FreeSqlSqlServerGlobalExtensions } internal static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); - /// - /// 使用merge on条件替换默认主键条件 - /// - /// - /// - /// - /// - /// - public static IInsertOrUpdate OnColumns(this IInsertOrUpdate that, params string[] columns) where T : class - { - var insertOrUpdate = that as FreeSql.SqlServer.Curd.SqlServerInsertOrUpdate; - if (insertOrUpdate == null) throw new Exception(CoreStrings.S_Features_Unique("OnColumns", "SqlServer")); - if (columns.Length > 0) - { - insertOrUpdate._columns = columns; - } - return that; - } - #region ExecuteSqlBulkCopy /// /// SqlServer SqlCopyBulk 批量插入功能 diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index 824e837f..8f6632ae 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -53,7 +53,7 @@ namespace FreeSql.Sqlite.Curd } else { - if (_table.Primarys.Any() == false) throw new Exception(CoreStrings.Entity_Must_Primary_Key("fsql.InsertOrUpdate + IfExistsDoNothing + Sqlite ", _table.CsName)); + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.Entity_Must_Primary_Key("fsql.InsertOrUpdate + IfExistsDoNothing + Sqlite ", _table.CsName)); sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => sb.Append(" \r\n WHERE NOT EXISTS(").Append( _orm.Select()