Skip to content

Commit 06b3013

Browse files
2881028810
authored andcommitted
- 补充 fsql.InsertOrUpdate UpdateColumns 数据存在时只更新指定的字段;
1 parent a8d1db8 commit 06b3013

File tree

19 files changed

+89
-26
lines changed

19 files changed

+89
-26
lines changed

FreeSql.DbContext/FreeSql.DbContext.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ public void AsType()
296296
public void EnableAddOrUpdateNavigateList_OneToMany()
297297
{
298298
var repo = g.sqlite.GetRepository<Cagetory>();
299+
repo.DbContextOptions.EnableAddOrUpdateNavigateList = true;
299300
var cts = new[] {
300301
new Cagetory
301302
{

FreeSql.Tests/FreeSql.Tests/UnitTest3.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ public Author123(long id, long songId)
159159
[Fact]
160160
public void Test03()
161161
{
162+
var sqlxx = g.pgsql.InsertOrUpdate<userinfo>().SetSource(new userinfo { userid = 10 }).UpdateColumns(a => new { a.birthday, a.CardNo }).ToSql();
163+
162164
var aff1 = g.sqlite.GetRepository<Edi, long>().Delete(10086);
163165
var aff2 = g.sqlite.Delete<Edi>(10086).ExecuteAffrows();
164166
Assert.Equal(aff1, aff2);

FreeSql/FreeSql.xml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

FreeSql/Interface/Curd/IInsertOrUpdate.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ public interface IInsertOrUpdate<T1> where T1 : class
4242
/// <returns></returns>
4343
IInsertOrUpdate<T1> IfExistsDoNothing();
4444

45+
/// <summary>
46+
/// 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"})
47+
/// </summary>
48+
/// <param name="columns">lambda选择列</param>
49+
/// <returns></returns>
50+
IInsertOrUpdate<T1> UpdateColumns(Expression<Func<T1, object>> columns);
51+
/// <summary>
52+
/// 当记录存在时,指定只更新的字段
53+
/// </summary>
54+
/// <param name="columns">属性名,或者字段名</param>
55+
/// <returns></returns>
56+
IInsertOrUpdate<T1> UpdateColumns(string[] columns);
57+
4558
/// <summary>
4659
/// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名;
4760
/// </summary>

FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@ namespace FreeSql.Internal.CommonProvider
1515

1616
public abstract partial class InsertOrUpdateProvider<T1> : IInsertOrUpdate<T1> where T1 : class
1717
{
18-
protected IFreeSql _orm;
19-
protected CommonUtils _commonUtils;
20-
protected CommonExpression _commonExpression;
21-
protected List<T1> _source = new List<T1>();
22-
protected bool _doNothing = false;
23-
protected Dictionary<string, bool> _auditValueChangedDict = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
24-
protected TableInfo _table;
25-
protected Func<string, string> _tableRule;
26-
protected DbParameter[] _params;
27-
protected DbTransaction _transaction;
28-
protected DbConnection _connection;
18+
public IFreeSql _orm;
19+
public CommonUtils _commonUtils;
20+
public CommonExpression _commonExpression;
21+
public List<T1> _source = new List<T1>();
22+
public bool _doNothing = false;
23+
public Dictionary<string, bool> _updateIgnore = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
24+
public Dictionary<string, bool> _auditValueChangedDict = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
25+
public TableInfo _table;
26+
public Func<string, string> _tableRule;
27+
public DbParameter[] _params;
28+
public DbTransaction _transaction;
29+
public DbConnection _connection;
2930
public ColumnInfo IdentityColumn { get; }
3031

3132
public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
@@ -57,6 +58,17 @@ public IInsertOrUpdate<T1> WithConnection(DbConnection connection)
5758
return this;
5859
}
5960

61+
public IInsertOrUpdate<T1> UpdateColumns(Expression<Func<T1, object>> columns) => UpdateColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null));
62+
public IInsertOrUpdate<T1> UpdateColumns(string[] columns)
63+
{
64+
var cols = columns.Distinct().ToDictionary(a => a);
65+
_updateIgnore.Clear();
66+
foreach (var col in _table.Columns.Values)
67+
if (cols.ContainsKey(col.Attribute.Name) == false && cols.ContainsKey(col.CsName) == false)
68+
_updateIgnore.Add(col.Attribute.Name, true);
69+
return this;
70+
}
71+
6072
public static void AuditDataValue(object sender, IEnumerable<T1> data, IFreeSql orm, TableInfo table, Dictionary<string, bool> changedDict)
6173
{
6274
if (data?.Any() != true) return;

Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ string getMergeSql(List<T1> data)
3737
WriteSourceSelectUnionAll(data, sb, dbParams);
3838
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
3939

40-
var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
40+
var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
4141
if (_doNothing == false && cols.Any())
4242
sb.Append("WHEN MATCHED THEN \r\n")
4343
.Append(" update set ").Append(string.Join(", ", cols.Select(a =>

Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ string getInsertSql(List<T1> data, bool flagInsert)
4444
{
4545
insert.InsertIdentity();
4646
if (_doNothing == false)
47-
sql = new OnDuplicateKeyUpdate<T1>(insert).ToSql();
47+
{
48+
var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
49+
sql = new OnDuplicateKeyUpdate<T1>(insert)
50+
.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray())
51+
.ToSql();
52+
}
4853
else
4954
{
5055
if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + MySql 要求实体类 {_table.CsName} 必须有主键");

Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ string getMergeSql(List<T1> data)
3737
WriteSourceSelectUnionAll(data, sb, dbParams);
3838
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n");
3939

40-
var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true);
40+
var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
4141
if (_doNothing == false && cols.Any())
4242
sb.Append("WHEN MATCHED THEN \r\n")
4343
.Append(" update set ").Append(string.Join(", ", cols.Select(a =>

Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ string getInsertSql(List<T1> data, bool flagInsert)
4343
else
4444
{
4545
var ocdu = new OdbcKingbaseESOnConflictDoUpdate<T1>(insert.InsertIdentity());
46-
ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray());
47-
if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false)
46+
var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
47+
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
48+
if (_doNothing == true || cols.Any() == false)
4849
ocdu.DoNothing();
4950
sql = ocdu.ToSql();
5051
}

0 commit comments

Comments
 (0)