diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/ExecuteNavProvider/UpdateNavOneToMany.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/ExecuteNavProvider/UpdateNavOneToMany.cs index 94dc66b13..ae8d4b341 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/ExecuteNavProvider/UpdateNavOneToMany.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/ExecuteNavProvider/UpdateNavOneToMany.cs @@ -11,9 +11,100 @@ namespace SqlSugar public NavigateType? _NavigateType { get; set; } private void UpdateOneToMany(string name, EntityColumnInfo nav) where TChild : class, new() { - DeleteInsert(name, nav); + if (_Options?.OneToManyInsertOrUpdate == true) + { + InsertOrUpdate(name,nav); + } + else + { + DeleteInsert(name, nav); + } + } + private void InsertOrUpdate(string name, EntityColumnInfo nav) where TChild : class, new() + { + List children = new List(); + var parentEntity = _ParentEntity; + var parentList = _ParentList; + var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); + var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); + var thisPkColumn = GetPkColumnByNav2(thisEntity, nav); + var thisFkColumn = GetFKColumnByNav(thisEntity, nav); + EntityColumnInfo parentPkColumn = GetParentPkColumn(); + EntityColumnInfo parentNavColumn = GetParentPkNavColumn(nav); + if (parentNavColumn != null) + { + parentPkColumn = parentNavColumn; + } + if (ParentIsPk(parentNavigateProperty)) + { + parentPkColumn = this._ParentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey); + } + var ids = new List(); + foreach (var item in parentList) + { + var parentValue = parentPkColumn.PropertyInfo.GetValue(item); + var childs = parentNavigateProperty.PropertyInfo.GetValue(item) as List; + if (childs != null) + { + foreach (var child in childs) + { + thisFkColumn.PropertyInfo.SetValue(child, parentValue, null); + } + children.AddRange(childs); + } + ids.Add(parentValue); + if (_Options?.OneToManyNoDeleteNull == true && childs == null) + { + ids.Remove(parentValue); + } + } + if (NotAny(name)) + { + DeleteMany(thisEntity, ids, thisFkColumn.DbColumnName); + if (this._Options?.OneToManyEnableLogicDelete == true) + { + var locgicColumn = thisEntity.Columns.FirstOrDefault(it => it.PropertyName.EqualCase("IsDeleted") || it.PropertyName.EqualCase("IsDelete")); + Check.ExceptionEasy( + locgicColumn == null, + thisEntity.EntityName + "Logical deletion requires the entity to have the IsDeleted property", + thisEntity.EntityName + "假删除需要实体有IsDeleted属性"); + List conditionalModels = new List(); + conditionalModels.Add(new ConditionalModel() + { + FieldName = thisFkColumn.DbColumnName, + FieldValue = string.Join(",", ids.Distinct()), + ConditionalType = ConditionalType.In, + CSharpTypeName = thisFkColumn?.PropertyInfo?.PropertyType?.Name + }); + var sqlObj = _Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); + this._Context.Updateable() + .AS(thisEntity.DbTableName) + .Where(sqlObj.Key, sqlObj.Value) + .SetColumns(locgicColumn.DbColumnName, true) + .ExecuteCommand(); + } + else + { + var list=this._Context.Queryable() + .AS(thisEntity.DbTableName) + .In(thisFkColumn.DbColumnName, ids.Distinct().ToList()) + .ToList(); + List result = GetNoExistsId(list, children, thisPkColumn.PropertyName); + if (result.Any()) + { + this._Context.Deleteable(result).ExecuteCommand(); + } + } + _NavigateType = NavigateType.OneToMany; + InsertDatas(children, thisPkColumn); + } + else + { + this._ParentList = children.Cast().ToList(); + } + _NavigateType = null; + SetNewParent(thisEntity, thisPkColumn); } - private void DeleteInsert(string name, EntityColumnInfo nav) where TChild : class, new() { List children = new List(); @@ -197,5 +288,33 @@ namespace SqlSugar this._ParentEntity = entityInfo; this._ParentPkColumn = entityColumnInfo; } + + public List GetNoExistsId(List old, List newList, string pkName) + { + List result = new List(); + + // 将newList中的主键属性转换为字符串集合 + var newIds = newList.Select(item => GetPropertyValueAsString(item, pkName)).ToList(); + + // 获取在old中但不在newList中的主键属性值 + result = old.Where(item => !newIds.Contains(GetPropertyValueAsString(item, pkName))) + .ToList(); + + return result; + } + + // 获取对象的属性值 + private string GetPropertyValueAsString(TChild item, string propertyName) + { + var property = item.GetType().GetProperty(propertyName); + if (property != null) + { + return property.GetValue(item, null)+""; + } + else + { + throw new ArgumentException($"Property '{propertyName}' not found on type {item.GetType().Name}"); + } + } } }