Skip to content

Commit b0ac5a8

Browse files
committed
- 调整 增加支持 OneToOne 级联保存,EnableAddOrUpdateNavigateList 改名为 EnableAddOrUpdateNavigate;
1 parent c9fa4d8 commit b0ac5a8

File tree

38 files changed

+190
-198
lines changed

38 files changed

+190
-198
lines changed

FreeSql.DbContext/DbContext/DbContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public DbContextOptions Options
4646
_optionsPriv = new DbContextOptions();
4747
if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(OrmOriginal.Ado.Identifier, out var opt))
4848
{
49-
_optionsPriv.EnableAddOrUpdateNavigateList = opt.EnableAddOrUpdateNavigateList;
49+
_optionsPriv.EnableAddOrUpdateNavigate = opt.EnableAddOrUpdateNavigate;
5050
_optionsPriv.EnableGlobalFilter = opt.EnableGlobalFilter;
5151
_optionsPriv.NoneParameter = opt.NoneParameter;
5252
_optionsPriv.OnEntityChange = opt.OnEntityChange;

FreeSql.DbContext/DbContext/DbContextOptions.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@ namespace FreeSql
77
{
88
public class DbContextOptions
99
{
10-
1110
/// <summary>
12-
/// 是否开启一对多,多对多级联保存功能<para></para>
11+
/// 是否开启 一对一(OneToOne)、一对多(OneToMany)、多对多(ManyToMany) 级联保存功能<para></para>
12+
/// <para></para>
13+
/// 【一对一】模型下,保存时级联保存 OneToOne 属性。
1314
/// <para></para>
14-
/// 【一对多】模型下, 保存时可级联保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。<para></para>
15+
/// 【一对多】模型下,保存时级联保存 OneToMany 集合属性。出于安全考虑我们没做完整对比,只针对实体属性集合的添加或更新操作,因此不会删除数据库表已有的数据。<para></para>
1516
/// 完整对比的功能使用起来太危险,试想下面的场景:<para></para>
16-
/// - 保存的时候,实体的属性集合是空的,如何操作?记录全部删除?<para></para>
17-
/// - 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作?<para></para>
17+
/// - 保存的时候,实体的属性集合为空时(!=null),表记录全部删除?<para></para>
18+
/// - 保存的时候,由于数据库子表的记录很多,只想保存子表的部分数据,又或者只需要添加,如何操作?
1819
/// <para></para>
19-
/// 【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(*注意不会更新)<para></para>
20+
/// 【多对多】模型下,对中间表的保存是完整对比操作,对外部实体的只作新增操作(*注意不会更新)<para></para>
2021
/// - 属性集合为空时(!=null),删除他们的所有关联数据(中间表)<para></para>
2122
/// - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录
2223
/// </summary>
23-
public bool EnableAddOrUpdateNavigateList { get; set; } = false;
24+
public bool EnableAddOrUpdateNavigate { get; set; } = false;
2425

2526
/// <summary>
2627
/// 使用无参数化设置(对应 IInsert/IUpdate)

FreeSql.DbContext/DbSet/DbSetAsync.cs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ async Task AddPrivAsync(TEntity data, bool isCheck, CancellationToken cancellati
5454
_db.OrmOriginal.SetEntityValueWithPropertyName(_entityType, data, _tableIdentitys[0].CsName, idtval);
5555
_db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert });
5656
Attach(data);
57-
if (_db.Options.EnableAddOrUpdateNavigateList)
58-
await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken);
57+
if (_db.Options.EnableAddOrUpdateNavigate)
58+
await AddOrUpdateNavigateAsync(data, true, null, cancellationToken);
5959
}
6060
else
6161
{
@@ -65,8 +65,8 @@ async Task AddPrivAsync(TEntity data, bool isCheck, CancellationToken cancellati
6565
IncrAffrows(1);
6666
_db.OrmOriginal.MapEntityValue(_entityType, newval, data);
6767
Attach(newval);
68-
if (_db.Options.EnableAddOrUpdateNavigateList)
69-
await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken);
68+
if (_db.Options.EnableAddOrUpdateNavigate)
69+
await AddOrUpdateNavigateAsync(data, true, null, cancellationToken);
7070
}
7171
return;
7272
default:
@@ -78,17 +78,17 @@ async Task AddPrivAsync(TEntity data, bool isCheck, CancellationToken cancellati
7878
_db.OrmOriginal.SetEntityValueWithPropertyName(_entityType, data, _tableIdentitys[0].CsName, idtval);
7979
_db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert });
8080
Attach(data);
81-
if (_db.Options.EnableAddOrUpdateNavigateList)
82-
await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken);
81+
if (_db.Options.EnableAddOrUpdateNavigate)
82+
await AddOrUpdateNavigateAsync(data, true, null, cancellationToken);
8383
return;
8484
}
8585
break;
8686
}
8787
}
8888
EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(data));
8989
Attach(data);
90-
if (_db.Options.EnableAddOrUpdateNavigateList)
91-
await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken);
90+
if (_db.Options.EnableAddOrUpdateNavigate)
91+
await AddOrUpdateNavigateAsync(data, true, null, cancellationToken);
9292
}
9393
public Task AddAsync(TEntity data, CancellationToken cancellationToken = default) => AddPrivAsync(data, true, cancellationToken);
9494
async public Task AddRangeAsync(IEnumerable<TEntity> data, CancellationToken cancellationToken = default)
@@ -120,9 +120,9 @@ async public Task AddRangeAsync(IEnumerable<TEntity> data, CancellationToken can
120120
_db.OrmOriginal.MapEntityValue(_entityType, rets[idx++], s);
121121
IncrAffrows(rets.Count);
122122
AttachRange(rets);
123-
if (_db.Options.EnableAddOrUpdateNavigateList)
123+
if (_db.Options.EnableAddOrUpdateNavigate)
124124
foreach (var item in data)
125-
await AddOrUpdateNavigateListAsync(item, true, null, cancellationToken);
125+
await AddOrUpdateNavigateAsync(item, true, null, cancellationToken);
126126
return;
127127
default:
128128
if (_tableIdentitys.Length == 1)
@@ -138,9 +138,9 @@ async public Task AddRangeAsync(IEnumerable<TEntity> data, CancellationToken can
138138
foreach (var item in data)
139139
EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(item));
140140
AttachRange(data);
141-
if (_db.Options.EnableAddOrUpdateNavigateList)
141+
if (_db.Options.EnableAddOrUpdateNavigate)
142142
foreach (var item in data)
143-
await AddOrUpdateNavigateListAsync(item, true, null, cancellationToken);
143+
await AddOrUpdateNavigateAsync(item, true, null, cancellationToken);
144144
}
145145

146146
async public Task SaveManyAsync(TEntity item, string propertyName, CancellationToken cancellationToken = default)
@@ -160,11 +160,11 @@ async public Task SaveManyAsync(TEntity item, string propertyName, CancellationT
160160
}
161161

162162
await DbContextFlushCommandAsync(cancellationToken);
163-
var oldEnable = _db.Options.EnableAddOrUpdateNavigateList;
164-
_db.Options.EnableAddOrUpdateNavigateList = false;
163+
var oldEnable = _db.Options.EnableAddOrUpdateNavigate;
164+
_db.Options.EnableAddOrUpdateNavigate = false;
165165
try
166166
{
167-
await AddOrUpdateNavigateListAsync(item, false, propertyName, cancellationToken);
167+
await AddOrUpdateNavigateAsync(item, false, propertyName, cancellationToken);
168168
if (tref.RefType == Internal.Model.TableRefType.OneToMany)
169169
{
170170
await DbContextFlushCommandAsync(cancellationToken);
@@ -197,10 +197,10 @@ async public Task SaveManyAsync(TEntity item, string propertyName, CancellationT
197197
}
198198
finally
199199
{
200-
_db.Options.EnableAddOrUpdateNavigateList = oldEnable;
200+
_db.Options.EnableAddOrUpdateNavigate = oldEnable;
201201
}
202202
}
203-
async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propertyName, CancellationToken cancellationToken)
203+
async Task AddOrUpdateNavigateAsync(TEntity item, bool isAdd, string propertyName, CancellationToken cancellationToken)
204204
{
205205
Func<PropertyInfo, Task> action = async prop =>
206206
{
@@ -213,15 +213,17 @@ async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propert
213213
switch (tref.RefType)
214214
{
215215
case Internal.Model.TableRefType.OneToOne:
216-
//var propValItem = GetItemValue(item, prop);
217-
//for (var colidx = 0; colidx < tref.Columns.Count; colidx++)
218-
//{
219-
// var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName));
220-
// _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val);
221-
//}
222-
//if (isAdd) await refSet.AddAsync(propValItem);
223-
//else await refSet.AddOrUpdateAsync(propValItem);
224-
//return;
216+
refSet = GetDbSetObject(tref.RefEntityType);
217+
var propValItem = GetItemValue(item, prop);
218+
if (propValItem == null) return;
219+
for (var colidx = 0; colidx < tref.Columns.Count; colidx++)
220+
{
221+
var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName));
222+
_db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val);
223+
}
224+
if (isAdd) await refSet.AddAsync(propValItem);
225+
else await refSet.AddOrUpdateAsync(propValItem);
226+
return;
225227
case Internal.Model.TableRefType.ManyToOne:
226228
return;
227229
}
@@ -441,9 +443,9 @@ async Task UpdateRangePrivAsync(IEnumerable<TEntity> data, bool isCheck, Cancell
441443
state.OldValue = item;
442444
EnqueueToDbContext(DbContext.EntityChangeType.Update, state);
443445
}
444-
if (_db.Options.EnableAddOrUpdateNavigateList)
446+
if (_db.Options.EnableAddOrUpdateNavigate)
445447
foreach (var item in data)
446-
await AddOrUpdateNavigateListAsync(item, false, null, cancellationToken);
448+
await AddOrUpdateNavigateAsync(item, false, null, cancellationToken);
447449
}
448450
#endregion
449451

0 commit comments

Comments
 (0)