diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs
index 88ef9f85..539f5183 100644
--- a/FreeSql.DbContext/DbContext/DbContext.cs
+++ b/FreeSql.DbContext/DbContext/DbContext.cs
@@ -136,6 +136,13 @@ namespace FreeSql
///
public void AddOrUpdate(TEntity data) where TEntity : class => this.Set().AddOrUpdate(data);
+ ///
+ /// 保存实体的指定 ManyToMany 导航属性
+ ///
+ /// 实体对象
+ /// 属性名
+ public void SaveManyToMany(TEntity data, string propertyName) where TEntity : class => this.Set().SaveManyToMany(data, propertyName);
+
///
/// 附加实体,可用于不查询就更新或删除
///
@@ -163,6 +170,7 @@ namespace FreeSql
public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data);
public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data);
+ public Task SaveManyToManyAsync(TEntity data, string propertyName) where TEntity : class => this.Set().SaveManyToManyAsync(data, propertyName);
#endif
#endregion
diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs
index de28479d..0adf77f3 100644
--- a/FreeSql.DbContext/DbSet/DbSetAsync.cs
+++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs
@@ -132,44 +132,58 @@ namespace FreeSql
await AddOrUpdateNavigateListAsync(item, true);
}
}
- async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd)
+
+ async public Task SaveManyToManyAsync(TEntity item, string propertyName)
+ {
+ if (item == null) return;
+ if (_table.Properties.ContainsKey(propertyName) == 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();
+ var oldEnable = _db.Options.EnableAddOrUpdateNavigateList;
+ _db.Options.EnableAddOrUpdateNavigateList = false;
+ await AddOrUpdateNavigateListAsync(item, false, propertyName);
+ _db.Options.EnableAddOrUpdateNavigateList = oldEnable;
+ }
+ async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propertyName = null)
{
Type itemType = null;
- foreach (var prop in _table.Properties)
+ Func action = async prop =>
{
- if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue;
- if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue;
+ if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) return;
+ if (_table.ColumnsByCs.ContainsKey(prop.Name)) return;
- var tref = _table.GetTableRef(prop.Key, true);
- if (tref == null) continue;
+ var tref = _table.GetTableRef(prop.Name, true);
+ if (tref == null) return;
switch (tref.RefType)
{
case Internal.Model.TableRefType.OneToOne:
case Internal.Model.TableRefType.ManyToOne:
- continue;
+ 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()).GetOrAdd(prop.Key, propName =>
+ var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).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) continue;
+ if (lazyFieldValue == false) return;
}
- propVal = prop.Value.GetValue(item);
+ propVal = prop.GetValue(item);
}
else
{
- propVal = prop.Value.GetValue(item);
- if (propVal == null) continue;
+ propVal = prop.GetValue(item);
+ if (propVal == null) return;
}
var propValEach = propVal as IEnumerable;
- if (propValEach == null) continue;
+ if (propValEach == null) return;
DbSet