mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 恢复 IBaseRepository SaveMany 方法;
This commit is contained in:
		@@ -843,5 +843,73 @@ namespace FreeSql
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比)<para></para>
 | 
			
		||||
        /// 场景:在关闭级联保存功能之后,手工使用本方法<para></para>
 | 
			
		||||
        /// 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus")<para></para>
 | 
			
		||||
        /// 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据<para></para>
 | 
			
		||||
        /// 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">实体对象</param>
 | 
			
		||||
        /// <param name="propertyName">属性名</param>
 | 
			
		||||
        public void SaveMany(TEntity item, string propertyName)
 | 
			
		||||
        {
 | 
			
		||||
            if (item == null) return;
 | 
			
		||||
            if (string.IsNullOrEmpty(propertyName)) return;
 | 
			
		||||
            if (_table.Properties.TryGetValue(propertyName, out var prop) == false) throw new KeyNotFoundException(DbContextStrings.NotFound_Property(_table.Type.FullName, propertyName));
 | 
			
		||||
            if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) throw new ArgumentException(DbContextStrings.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(DbContextStrings.PropertyOfType_IsNot_OneToManyOrManyToMany(_table.Type.FullName, propertyName));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            DbContextFlushCommand();
 | 
			
		||||
            var oldEnable = _db.Options.EnableCascadeSave;
 | 
			
		||||
            _db.Options.EnableCascadeSave = false;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                AddOrUpdateNavigate(item, false, propertyName);
 | 
			
		||||
                if (tref.RefType == TableRefType.OneToMany)
 | 
			
		||||
                {
 | 
			
		||||
                    DbContextFlushCommand();
 | 
			
		||||
                    //删除没有保存的数据,求出主体的条件
 | 
			
		||||
                    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;
 | 
			
		||||
                    }
 | 
			
		||||
                    subDelete.ExecuteAffrows();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _db.Options.EnableCascadeSave = oldEnable;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user