Skip to content

Commit

Permalink
- 恢复 BaseEntity SaveMany 方法;
Browse files Browse the repository at this point in the history
  • Loading branch information
2881099 committed Nov 22, 2024
1 parent e0369ac commit 85e732f
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,16 @@ async Task<int> DeleteWithinBoundaryAsync(IEnumerable<TEntity> entitys, List<obj
return affrows;
}

async public virtual Task SaveManyAsync(TEntity entity, string propertyName, CancellationToken cancellationToken = default)
{
var tracking = new AggregateRootTrackingChangeInfo();
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
if (_states.TryGetValue(stateKey, out var state) == false) throw new Exception($"AggregateRootRepository 使用仓储对象查询后,才可以保存数据 {Orm.GetEntityString(EntityType, entity)}");
AggregateRootUtils.CompareEntityValue(_boundaryName, Orm, EntityType, state.Value, entity, propertyName, tracking);
await SaveTrackingChangeAsync(tracking, cancellationToken);
Attach(entity); //应该只存储 propertyName 内容
}

async Task<int> SaveTrackingChangeAsync(AggregateRootTrackingChangeInfo tracking, CancellationToken cancellationToken)
{
var affrows = 0;
Expand Down
13 changes: 13 additions & 0 deletions Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,18 @@ public virtual TEntity Save()
Repository.UnitOfWork = _resolveUow?.Invoke();
return Repository.InsertOrUpdate(this as TEntity);
}

/// <summary>
/// To completely save the navigation properties of the entity in the form of sub-tables. <br />
/// 【完整】保存导航属性,子表
/// </summary>
/// <param name="navigatePropertyName">Navigation property name</param>
public virtual void SaveMany(string navigatePropertyName)
{
if (Repository == null)
Repository = Orm.GetRepository<TEntity>();
Repository.UnitOfWork = _resolveUow?.Invoke();
Repository.SaveMany(this as TEntity, navigatePropertyName);
}
}
}
13 changes: 13 additions & 0 deletions Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,19 @@ public virtual Task<TEntity> SaveAsync()
Repository.UnitOfWork = _resolveUow?.Invoke();
return Repository.InsertOrUpdateAsync(this as TEntity);
}

/// <summary>
/// To completely save the navigation properties of the entity in the form of sub-tables. <br />
/// 【完整】保存导航属性,子表
/// </summary>
/// <param name="navigatePropertyName">Navigation property name</param>
public virtual Task SaveManyAsync(string navigatePropertyName)
{
if (Repository == null)
Repository = Orm.GetRepository<TEntity>();
Repository.UnitOfWork = _resolveUow?.Invoke();
return Repository.SaveManyAsync(this as TEntity, navigatePropertyName);
}
#endif
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions FreeSql.DbContext/DbSet/DbSetAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,65 @@ async public Task AddRangeAsync(IEnumerable<TEntity> data, CancellationToken can
await AddOrUpdateNavigateAsync(item, true, null, cancellationToken);
}

async public Task SaveManyAsync(TEntity item, string propertyName, CancellationToken cancellationToken = default)
{
if (item == null) return;
if (string.IsNullOrEmpty(propertyName)) return;
if (_table.Properties.TryGetValue(propertyName, out var prop) == false) throw new KeyNotFoundException(DbContextErrorStrings.NotFound_Property(_table.Type.FullName, propertyName));
if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) throw new ArgumentException(DbContextErrorStrings.TypeHasSetProperty_IgnoreAttribute(_table.Type.FullName, propertyName));

var tref = _table.GetTableRef(propertyName, true, false);
if (tref == null) return;
switch (tref.RefType)
{
case TableRefType.OneToOne:
case TableRefType.ManyToOne:
case TableRefType.PgArrayToMany:
throw new ArgumentException(DbContextErrorStrings.PropertyOfType_IsNot_OneToManyOrManyToMany(_table.Type.FullName, propertyName));
}

await DbContextFlushCommandAsync(cancellationToken);
var oldEnable = _db.Options.EnableCascadeSave;
_db.Options.EnableCascadeSave = false;
try
{
await AddOrUpdateNavigateAsync(item, false, propertyName, cancellationToken);
if (tref.RefType == TableRefType.OneToMany)
{
await DbContextFlushCommandAsync(cancellationToken);
//删除没有保存的数据,求出主体的条件
var deleteWhereParentParam = Expression.Parameter(typeof(object), "a");
Expression whereParentExp = null;
for (var colidx = 0; colidx < tref.Columns.Count; colidx++)
{
var whereExp = Expression.Equal(
Expression.MakeMemberAccess(Expression.Convert(deleteWhereParentParam, tref.RefEntityType), tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName]),
Expression.Constant(
FreeSql.Internal.Utils.GetDataReaderValue(
tref.Columns[colidx].CsType,
_db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType)
);
if (whereParentExp == null) whereParentExp = whereExp;
else whereParentExp = Expression.AndAlso(whereParentExp, whereExp);
}
var propValEach = GetItemValue(item, prop) as IEnumerable;
var subDelete = _db.OrmOriginal.Delete<object>().AsType(tref.RefEntityType)
.WithTransaction(_uow?.GetOrBeginTransaction())
.Where(Expression.Lambda<Func<object, bool>>(whereParentExp, deleteWhereParentParam));
foreach (var propValItem in propValEach)
{
subDelete.WhereDynamic(propValEach, true);
break;
}
await subDelete.ExecuteAffrowsAsync(cancellationToken);
}
}
finally
{
_db.Options.EnableCascadeSave = oldEnable;
}
}

async Task AddOrUpdateNavigateAsync(TEntity item, bool isAdd, string propertyName, CancellationToken cancellationToken)
{
Func<PropertyInfo, Task> action = async prop =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ public virtual async Task<TEntity> InsertOrUpdateAsync(TEntity entity, Cancellat
await _db.SaveChangesAsync(cancellationToken);
return entity;
}

public virtual async Task SaveManyAsync(TEntity entity, string propertyName, CancellationToken cancellationToken = default)
{
await _dbset.SaveManyAsync(entity, propertyName, cancellationToken);
await _db.SaveChangesAsync(cancellationToken);
}
}

partial class BaseRepository<TEntity, TKey>
Expand Down
1 change: 1 addition & 0 deletions FreeSql.DbContext/Repository/Repository/IBaseRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public interface IBaseRepository<TEntity> : IBaseRepository
Task<int> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);
Task<int> UpdateAsync(IEnumerable<TEntity> entitys, CancellationToken cancellationToken = default);
Task<TEntity> InsertOrUpdateAsync(TEntity entity, CancellationToken cancellationToken = default);
Task SaveManyAsync(TEntity entity, string propertyName, CancellationToken cancellationToken = default);

Task<int> DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);
Task<int> DeleteAsync(IEnumerable<TEntity> entitys, CancellationToken cancellationToken = default);
Expand Down
153 changes: 30 additions & 123 deletions FreeSql/FreeSql.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 85e732f

Please sign in to comment.