using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace SqlSugar { public partial class UpdateNavProvider where T : class, new() where Root : class, new() { private void UpdateManyToMany(string name, EntityColumnInfo nav) where TChild : class, new() { var parentEntity = _ParentEntity; var parentList = _ParentList; var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name); var thisEntity = this._Context.EntityMaintenance.GetEntityInfo(); var thisPkColumn = thisEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); Check.ExceptionEasy(thisPkColumn == null, $"{thisPkColumn.EntityName} need primary key", $"{thisPkColumn.EntityName}需要主键"); Check.ExceptionEasy(parentPkColumn == null, $"{parentPkColumn.EntityName} need primary key", $"{parentPkColumn.EntityName}需要主键"); var mappingType = parentNavigateProperty.Navigat.MappingType; var mappingEntity = this._Context.EntityMaintenance.GetEntityInfo(mappingType); var mappingA = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingAId); var mappingB = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingBId); Check.ExceptionEasy(mappingA == null || mappingB == null, $"Navigate property {name} error ", $"导航属性{name}配置错误"); var mappingPk = mappingEntity.Columns .Where(it => it.PropertyName != mappingA.PropertyName) .Where(it => it.PropertyName != mappingB.PropertyName) .Where(it => it.IsPrimarykey && !it.IsIdentity && it.OracleSequenceName.IsNullOrEmpty()).FirstOrDefault(); var mappingOthers = mappingEntity.Columns .Where(it => it.PropertyName != mappingA.PropertyName) .Where(it => it.PropertyName != mappingB.PropertyName) .Where(it=>!it.IsIdentity) .Where(it => !it.IsPrimarykey) .Where(it => !it.IsOnlyIgnoreInsert) .Where(it => !it.IsIgnore); List> mappgingTables = new List>(); var ids=new List(); foreach (var item in parentList) { var items = parentNavigateProperty.PropertyInfo.GetValue(item); if (items == null) { continue; } var children = ((List)items); if (this._Options != null && this._Options.ManyToManyIsUpdateB) { InsertDatas(children, thisPkColumn); } else { _ParentList = children.Cast().ToList(); } var parentId = parentPkColumn.PropertyInfo.GetValue(item); if (!ids.Contains(parentId)) { ids.Add(parentId); } foreach (var child in children) { var chidId = thisPkColumn.PropertyInfo.GetValue(child); Dictionary keyValuePairs = new Dictionary(); keyValuePairs.Add(mappingA.DbColumnName, parentId); keyValuePairs.Add(mappingB.DbColumnName, chidId); if (mappingOthers != null) { foreach (var pair in mappingOthers) { if (pair.UnderType == UtilConstants.DateType) { keyValuePairs.Add(pair.DbColumnName, DateTime.Now); } else if (pair.UnderType == UtilConstants.StringType) { keyValuePairs.Add(pair.DbColumnName, UtilConstants.Space); } else { keyValuePairs.Add(pair.DbColumnName, UtilMethods.GetDefaultValue(pair.UnderType)); } } } if (mappingPk != null) { SetMappingTableDefaultValue(mappingPk, keyValuePairs); } mappgingTables.Add(keyValuePairs); } } if (this._Options?.ManyToManyEnableLogicDelete == 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 = mappingA.DbColumnName, FieldValue = string.Join(",", ids.Distinct()), ConditionalType = ConditionalType.In, CSharpTypeName = mappingA?.PropertyInfo?.PropertyType?.Name }); var sqlObj = _Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels); this._Context.Updateable() .AS(mappingEntity.DbTableName) .Where(sqlObj.Key, sqlObj.Value) .SetColumns(locgicColumn.DbColumnName, true) .ExecuteCommand(); } else if (_Context?.CurrentConnectionConfig?.MoreSettings?.IsAutoDeleteQueryFilter == true) { this._Context.Deleteable().AS(mappingEntity.DbTableName).In(mappingA.DbColumnName, ids).EnableQueryFilter(mappingEntity.Type).ExecuteCommand(); } else { this._Context.Deleteable().AS(mappingEntity.DbTableName).In(mappingA.DbColumnName, ids).ExecuteCommand(); } if (HasMappingTemplate(mappingEntity)) { InertMappingWithTemplate(mappingEntity, mappingA, mappingB, mappgingTables); } else { this._Context.Insertable(mappgingTables).AS(mappingEntity.DbTableName).ExecuteCommand(); } _ParentEntity = thisEntity; } private bool HasMappingTemplate(EntityInfo mappingEntity) { return this._Options?.ManyToManySaveMappingTemplate?.GetType() == mappingEntity.Type; } private void InertMappingWithTemplate(EntityInfo mappingEntity, EntityColumnInfo mappingA, EntityColumnInfo mappingB, List> mappgingTables) { var template = this._Options?.ManyToManySaveMappingTemplate; List mappingObjects = new List(); foreach (var item in mappgingTables) { // 序列化模板对象 var serializedTemplate = JsonConvert.SerializeObject(template); // 反序列化模板对象,创建新的映射对象 var mappingObject = JsonConvert.DeserializeObject(serializedTemplate, template.GetType()); // 获取映射对象的所有字段 var fields = mappingEntity.Columns; // 遍历字典中的键值对,并将值赋给映射对象的对应字段 foreach (var kvp in item) { var fieldName = kvp.Key; var fieldValue = kvp.Value; // 查找与字段名匹配的字段 var field = fields.FirstOrDefault(f => f.DbColumnName.EqualCase(fieldName)); // 如果字段存在且值的类型与字段类型匹配,则赋值给字段 if (field != null) { var isSetValue = field.IsPrimarykey || field.DbColumnName == mappingA.DbColumnName || field.DbColumnName == mappingB.DbColumnName; if (isSetValue) field.PropertyInfo.SetValue(mappingObject, fieldValue); } } // 将映射对象添加到列表中 mappingObjects.Add(mappingObject); } this._Context.InsertableByObject(mappingObjects).ExecuteCommand(); } private void SetMappingTableDefaultValue(EntityColumnInfo mappingPk, Dictionary keyValuePairs) { if (mappingPk.UnderType == UtilConstants.LongType) { keyValuePairs.Add(mappingPk.DbColumnName, SnowFlakeSingle.Instance.NextId()); } else if (mappingPk.UnderType == UtilConstants.GuidType) { keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid()); } else if (mappingPk.UnderType == UtilConstants.StringType) { keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid() + ""); } else { var name = mappingPk.EntityName + " " + mappingPk.DbColumnName; Check.ExceptionEasy($"The field {name} is not an autoassignment type and requires an assignment", $" 中间表主键字段{name}不是可自动赋值类型, 可赋值类型有 自增、long、Guid、string。你也可以删掉主键 用双主键"); } } } }