InsertNavProviderManyToMany.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace SqlSugar
  9. {
  10. public partial class InsertNavProvider<Root, T> where T : class, new() where Root : class, new()
  11. {
  12. private void InsertManyToMany<TChild>(string name, EntityColumnInfo nav) where TChild : class, new()
  13. {
  14. ;
  15. var parentEntity = _ParentEntity;
  16. var parentList = _ParentList;
  17. var parentPkColumn = parentEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true);
  18. var parentNavigateProperty = parentEntity.Columns.FirstOrDefault(it => it.PropertyName == name);
  19. var thisEntity = this._Context.EntityMaintenance.GetEntityInfo<TChild>();
  20. var thisPkColumn = thisEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true);
  21. Check.ExceptionEasy(thisPkColumn == null, $"{thisPkColumn.EntityName} need primary key", $"{thisPkColumn.EntityName}需要主键");
  22. Check.ExceptionEasy(parentPkColumn == null, $"{parentPkColumn.EntityName} need primary key", $"{parentPkColumn.EntityName}需要主键");
  23. var mappingType = parentNavigateProperty.Navigat.MappingType;
  24. var mappingEntity = this._Context.EntityMaintenance.GetEntityInfo(mappingType);
  25. var mappingA = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingAId);
  26. var mappingB = mappingEntity.Columns.FirstOrDefault(x => x.PropertyName == parentNavigateProperty.Navigat.MappingBId);
  27. Check.ExceptionEasy(mappingA == null || mappingB == null, $"Navigate property {name} error ", $"导航属性{name}配置错误");
  28. var mappingPk = mappingEntity.Columns
  29. .Where(it => it.PropertyName != mappingA.PropertyName)
  30. .Where(it => it.PropertyName != mappingB.PropertyName)
  31. .Where(it => it.IsPrimarykey && !it.IsIdentity && it.OracleSequenceName.IsNullOrEmpty()).FirstOrDefault();
  32. var mappingOthers = mappingEntity.Columns
  33. .Where(it => it.PropertyName != mappingA.PropertyName)
  34. .Where(it => it.PropertyName != mappingB.PropertyName)
  35. .Where(it => !it.IsIdentity)
  36. .Where(it => !it.IsOnlyIgnoreInsert)
  37. .Where(it => !it.IsIgnore)
  38. .Where(it => !it.IsPrimarykey);
  39. List<Dictionary<string, object>> mappgingTables = new List<Dictionary<string, object>>();
  40. foreach (var item in parentList)
  41. {
  42. var items = parentNavigateProperty.PropertyInfo.GetValue(item);
  43. if (items == null)
  44. {
  45. continue;
  46. }
  47. var children = ((List<TChild>)items);
  48. InsertDatas(children, thisPkColumn);
  49. var parentId = parentPkColumn.PropertyInfo.GetValue(item);
  50. foreach (var child in children)
  51. {
  52. var chidId = thisPkColumn.PropertyInfo.GetValue(child);
  53. Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
  54. keyValuePairs.Add(mappingA.DbColumnName, parentId);
  55. keyValuePairs.Add(mappingB.DbColumnName, chidId);
  56. if (mappingOthers != null)
  57. {
  58. foreach (var pair in mappingOthers)
  59. {
  60. if (!keyValuePairs.ContainsKey(pair.DbColumnName))
  61. {
  62. if (pair.UnderType == UtilConstants.DateType)
  63. {
  64. keyValuePairs.Add(pair.DbColumnName, DateTime.Now);
  65. }
  66. else if (pair.UnderType == UtilConstants.StringType)
  67. {
  68. keyValuePairs.Add(pair.DbColumnName, UtilConstants.Space);
  69. }
  70. else
  71. {
  72. keyValuePairs.Add(pair.DbColumnName, UtilMethods.GetDefaultValue(pair.UnderType));
  73. }
  74. }
  75. }
  76. }
  77. if (mappingPk != null)
  78. {
  79. SetMappingTableDefaultValue(mappingPk, keyValuePairs);
  80. }
  81. mappgingTables.Add(keyValuePairs);
  82. }
  83. }
  84. var ids = mappgingTables.Select(x => x[mappingA.DbColumnName]).ToList();
  85. if (_navOptions != null && _navOptions.ManyToManyNoDeleteMap)
  86. {
  87. //The reserved
  88. }
  89. else
  90. {
  91. this._Context.Deleteable<object>().AS(mappingEntity.DbTableName).In(mappingA.DbColumnName, ids).ExecuteCommand();
  92. }
  93. if (HasMappingTemplate(mappingEntity))
  94. {
  95. InertMappingWithTemplate(mappingEntity, mappingA, mappingB, mappgingTables);
  96. }
  97. else
  98. {
  99. this._Context.Insertable(mappgingTables).AS(mappingEntity.DbTableName).ExecuteCommand();
  100. }
  101. SetNewParent<TChild>(thisEntity, thisPkColumn);
  102. }
  103. private void InertMappingWithTemplate(EntityInfo mappingEntity, EntityColumnInfo mappingA, EntityColumnInfo mappingB, List<Dictionary<string, object>> mappgingTables)
  104. {
  105. var template = this._navOptions?.ManyToManySaveMappingTemplate;
  106. List<object> mappingObjects = new List<object>();
  107. foreach (var item in mappgingTables)
  108. {
  109. // 序列化模板对象
  110. var serializedTemplate = JsonConvert.SerializeObject(template);
  111. // 反序列化模板对象,创建新的映射对象
  112. var mappingObject = JsonConvert.DeserializeObject(serializedTemplate, template.GetType());
  113. // 获取映射对象的所有字段
  114. var fields = mappingEntity.Columns;
  115. // 遍历字典中的键值对,并将值赋给映射对象的对应字段
  116. foreach (var kvp in item)
  117. {
  118. var fieldName = kvp.Key;
  119. var fieldValue = kvp.Value;
  120. // 查找与字段名匹配的字段
  121. var field = fields.FirstOrDefault(f => f.DbColumnName.EqualCase(fieldName));
  122. // 如果字段存在且值的类型与字段类型匹配,则赋值给字段
  123. if (field != null)
  124. {
  125. var isSetValue = field.IsPrimarykey
  126. || field.DbColumnName == mappingA.DbColumnName
  127. || field.DbColumnName == mappingB.DbColumnName;
  128. if (isSetValue)
  129. field.PropertyInfo.SetValue(mappingObject, fieldValue);
  130. }
  131. }
  132. // 将映射对象添加到列表中
  133. mappingObjects.Add(mappingObject);
  134. }
  135. this._Context.InsertableByObject(mappingObjects).ExecuteCommand();
  136. }
  137. private bool HasMappingTemplate(EntityInfo mappingEntity)
  138. {
  139. return this._navOptions?.ManyToManySaveMappingTemplate?.GetType() == mappingEntity.Type;
  140. }
  141. private void SetMappingTableDefaultValue(EntityColumnInfo mappingPk, Dictionary<string, object> keyValuePairs)
  142. {
  143. if (mappingPk.UnderType == UtilConstants.LongType)
  144. {
  145. keyValuePairs.Add(mappingPk.DbColumnName, SnowFlakeSingle.Instance.NextId());
  146. }
  147. else if (mappingPk.UnderType == UtilConstants.GuidType)
  148. {
  149. keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid());
  150. }
  151. else if (mappingPk.UnderType == UtilConstants.StringType)
  152. {
  153. keyValuePairs.Add(mappingPk.DbColumnName, Guid.NewGuid() + "");
  154. }
  155. else
  156. {
  157. var name= mappingPk.EntityName+" "+ mappingPk.DbColumnName;
  158. Check.ExceptionEasy($"The field {name} is not an autoassignment type and requires an assignment",
  159. $" 中间表主键字段{name}不是可自动赋值类型, 可赋值类型有 自增、long、Guid、string。你也可以删掉主键 用双主键");
  160. }
  161. }
  162. }
  163. }