- 增加 Repository/DbContext SaveMany 方法实现一对多,子数据的完整保存;

- 调整 SaveManyToMany 方法名为 SaveMany;
This commit is contained in:
28810
2019-11-21 16:42:20 +08:00
parent b5629b13a6
commit 04107d3d24
15 changed files with 150 additions and 109 deletions

View File

@ -133,22 +133,44 @@ namespace FreeSql
}
}
async public Task SaveManyToManyAsync(TEntity item, string propertyName)
async public Task SaveManyAsync(TEntity item, string propertyName)
{
if (item == null) return;
if (_table.Properties.ContainsKey(propertyName) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}");
if (string.IsNullOrEmpty(propertyName)) return;
if (_table.Properties.TryGetValue(propertyName, out var prop) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}");
if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) throw new ArgumentException($"{_table.Type.FullName} 类型已设置属性 {propertyName} 忽略特性");
var tref = _table.GetTableRef(propertyName, true);
if (tref.RefType != Internal.Model.TableRefType.ManyToMany) throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 ManyToMany 特性");
DbContextExecCommand();
if (tref == null) return;
switch (tref.RefType)
{
case Internal.Model.TableRefType.OneToOne:
case Internal.Model.TableRefType.ManyToOne:
throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性");
}
await DbContextExecCommandAsync();
var oldEnable = _db.Options.EnableAddOrUpdateNavigateList;
_db.Options.EnableAddOrUpdateNavigateList = false;
await AddOrUpdateNavigateListAsync(item, false, propertyName);
_db.Options.EnableAddOrUpdateNavigateList = oldEnable;
try
{
await AddOrUpdateNavigateListAsync(item, false, propertyName);
if (tref.RefType == Internal.Model.TableRefType.OneToMany)
{
await DbContextExecCommandAsync();
//删除没有保存的数据
var propValEach = GetItemValue(item, prop) as IEnumerable;
await _db.Orm.Select<object>().AsType(tref.RefEntityType).WhereDynamic(propValEach, true)
.ToDelete().ExecuteAffrowsAsync();
}
}
finally
{
_db.Options.EnableAddOrUpdateNavigateList = oldEnable;
}
}
async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propertyName = null)
{
Type itemType = null;
Func<PropertyInfo, Task> action = async prop =>
{
if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) return;
@ -163,26 +185,7 @@ namespace FreeSql
return;
}
object propVal = null;
if (itemType == null) itemType = item.GetType();
if (_table.TypeLazy != null && itemType == _table.TypeLazy)
{
var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary<string, FieldInfo>()).GetOrAdd(prop.Name, propName =>
_table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance));
if (lazyField != null)
{
var lazyFieldValue = (bool)lazyField.GetValue(item);
if (lazyFieldValue == false) return;
}
propVal = prop.GetValue(item);
}
else
{
propVal = prop.GetValue(item);
if (propVal == null) return;
}
var propValEach = propVal as IEnumerable;
var propValEach = GetItemValue(item, prop) as IEnumerable;
if (propValEach == null) return;
DbSet<object> refSet = GetDbSetObject(tref.RefEntityType);
switch (tref.RefType)