SubInserable.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.SqlTypes;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace SqlSugar
  9. {
  10. public class SubInsertable<T> : ISubInsertable<T> where T : class, new()
  11. {
  12. internal EntityInfo Entity { get; set; }
  13. internal List<SubInsertTreeExpression> SubList { get; set; }
  14. internal SqlSugarProvider Context { get; set; }
  15. internal T[] InsertObjects { get; set; }
  16. internal InsertBuilder InsertBuilder { get; set; }
  17. internal string Pk { get; set; }
  18. public ISubInsertable<T> AddSubList(Expression<Func<T, object>> items)
  19. {
  20. if (this.SubList == null)
  21. this.SubList = new List<SubInsertTreeExpression>();
  22. this.SubList.Add(new SubInsertTreeExpression() { Expression = items });
  23. return this;
  24. }
  25. public ISubInsertable<T> AddSubList(Expression<Func<T, SubInsertTree>> tree)
  26. {
  27. try
  28. {
  29. var lamda = (tree as LambdaExpression);
  30. var memInit = lamda.Body as MemberInitExpression;
  31. if (memInit.Bindings != null)
  32. {
  33. MemberAssignment memberAssignment = (MemberAssignment)memInit.Bindings[0];
  34. SubList.Add(new SubInsertTreeExpression()
  35. {
  36. Expression = memberAssignment.Expression,
  37. Childs = GetSubInsertTree(((MemberAssignment)memInit.Bindings[1]).Expression)
  38. });
  39. }
  40. }
  41. catch
  42. {
  43. Check.Exception(true, tree.ToString() + " format error ");
  44. }
  45. return this;
  46. }
  47. private List<SubInsertTreeExpression> GetSubInsertTree(Expression expression)
  48. {
  49. List<SubInsertTreeExpression> resul = new List<SubInsertTreeExpression>();
  50. if (expression is ListInitExpression)
  51. {
  52. ListInitExpression exp = expression as ListInitExpression;
  53. foreach (var item in exp.Initializers)
  54. {
  55. SubInsertTreeExpression tree = new SubInsertTreeExpression();
  56. var memInit = item.Arguments[0] as MemberInitExpression;
  57. if (memInit.Bindings != null)
  58. {
  59. MemberAssignment memberAssignment = (MemberAssignment)memInit.Bindings[0];
  60. tree.Expression = memberAssignment.Expression;
  61. if (memInit.Bindings.Count > 1)
  62. {
  63. tree.Childs = GetSubInsertTree(((MemberAssignment)memInit.Bindings[1]).Expression);
  64. }
  65. }
  66. resul.Add(tree);
  67. }
  68. }
  69. else
  70. {
  71. }
  72. return resul;
  73. }
  74. [Obsolete("use ExecuteCommand")]
  75. public object ExecuteReturnPrimaryKey()
  76. {
  77. return ExecuteCommand();
  78. }
  79. public async Task<object> ExecuteCommandAsync()
  80. {
  81. object resut = 0;
  82. await Task.Run(() =>
  83. {
  84. resut= ExecuteCommand();
  85. });
  86. return resut;
  87. }
  88. public object ExecuteCommand()
  89. {
  90. var isNoTrean = this.Context.Ado.Transaction == null;
  91. try
  92. {
  93. if (isNoTrean)
  94. this.Context.Ado.BeginTran();
  95. var result = Execute();
  96. if (isNoTrean)
  97. this.Context.Ado.CommitTran();
  98. return result;
  99. }
  100. catch (Exception ex)
  101. {
  102. if (isNoTrean)
  103. this.Context.Ado.RollbackTran();
  104. throw ex;
  105. }
  106. }
  107. private object Execute()
  108. {
  109. if (InsertObjects != null && InsertObjects.Count() > 0)
  110. {
  111. var isIdEntity = IsIdEntity(this.Entity);
  112. if (!isIdEntity)
  113. {
  114. this.Context.Insertable(InsertObjects).ExecuteCommand();
  115. }
  116. foreach (var InsertObject in InsertObjects)
  117. {
  118. int id = 0;
  119. if (isIdEntity)
  120. {
  121. id = this.Context.Insertable(InsertObject).ExecuteReturnIdentity();
  122. this.Entity.Columns.First(it => it.IsIdentity || it.OracleSequenceName.HasValue()).PropertyInfo.SetValue(InsertObject, id);
  123. }
  124. var pk = GetPrimaryKey(this.Entity, InsertObject, id);
  125. AddChildList(this.SubList, InsertObject, pk);
  126. }
  127. return InsertObjects.Count();
  128. }
  129. else
  130. {
  131. return 0;
  132. }
  133. }
  134. [Obsolete("use ExecuteCommandAsync")]
  135. public Task<object> ExecuteReturnPrimaryKeyAsync()
  136. {
  137. return Task.FromResult(ExecuteReturnPrimaryKey());
  138. }
  139. private bool IsIdEntity(EntityInfo entity)
  140. {
  141. return entity.Columns.Where(it => it.IsIdentity||it.OracleSequenceName.HasValue()).Count() > 0;
  142. }
  143. private void AddChildList(List<SubInsertTreeExpression> items, object insertObject, object pkValue)
  144. {
  145. if (items != null)
  146. {
  147. foreach (var item in items)
  148. {
  149. MemberExpression subMemberException;
  150. string subMemberName = GetMemberName(item, out subMemberException);
  151. string childName = GetChildName(item, subMemberException);
  152. var childListProperty = insertObject.GetType().GetProperty(childName);
  153. if (childListProperty == null)
  154. {
  155. childName = subMemberName;
  156. childListProperty = insertObject.GetType().GetProperty(childName);
  157. }
  158. var childList = childListProperty.GetValue(insertObject);
  159. if (childList != null)
  160. {
  161. if (!(childList is IEnumerable<object>))
  162. {
  163. childList = new List<object>() { childList };
  164. }
  165. if (!string.IsNullOrEmpty(subMemberName) &&subMemberName!=childName)
  166. {
  167. foreach (var child in childList as IEnumerable<object>)
  168. {
  169. child.GetType().GetProperty(subMemberName).SetValue(child, pkValue);
  170. }
  171. }
  172. if (!(childList as IEnumerable<object>).Any())
  173. {
  174. continue;
  175. }
  176. var type = (childList as IEnumerable<object>).First().GetType();
  177. this.Context.InitMappingInfo(type);
  178. var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type);
  179. var isIdentity = IsIdEntity(entityInfo);
  180. var tableName = entityInfo.DbTableName;
  181. List<Dictionary<string, object>> insertList = new List<Dictionary<string, object>>();
  182. var entityList = (childList as IEnumerable<object>).ToList();
  183. foreach (var child in entityList)
  184. {
  185. insertList.Add(GetInsertDictionary(child, entityInfo));
  186. }
  187. if (!isIdentity)
  188. {
  189. this.Context.Insertable(insertList).AS(tableName).ExecuteCommand();
  190. }
  191. int i = 0;
  192. foreach (var insert in insertList)
  193. {
  194. int id = 0;
  195. if (isIdentity)
  196. {
  197. if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL)
  198. {
  199. var sqlobj = this.Context.Insertable(insert).AS(tableName).ToSql();
  200. id = this.Context.Ado.GetInt(sqlobj.Key+ " "+ this.InsertBuilder.Builder.GetTranslationColumnName(entityInfo.Columns.First(it=>isIdentity).DbColumnName), sqlobj.Value);
  201. }
  202. else
  203. {
  204. id = this.Context.Insertable(insert).AS(tableName).ExecuteReturnIdentity();
  205. }
  206. if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle&&id==0)
  207. {
  208. var seqName=entityInfo.Columns.First(it => it.OracleSequenceName.HasValue())?.OracleSequenceName;
  209. id = this.Context.Ado.GetInt("select "+seqName+".currval from dual");
  210. }
  211. }
  212. var entity = entityList[i];
  213. var pk = GetPrimaryKey(entityInfo,entity, id);
  214. AddChildList(item.Childs, entity, pk);
  215. ++i;
  216. }
  217. }
  218. }
  219. }
  220. }
  221. private Dictionary<string, object> GetInsertDictionary(object insetObject, EntityInfo subEntity)
  222. {
  223. Dictionary<string, object> insertDictionary = new Dictionary<string, object>();
  224. foreach (var item in subEntity.Columns)
  225. {
  226. if (item.IsIdentity || item.IsIgnore)
  227. {
  228. }
  229. else if (!string.IsNullOrEmpty(item.OracleSequenceName) && this.Context.CurrentConnectionConfig.DbType == DbType.Oracle)
  230. {
  231. var value = "{SugarSeq:=}" + item.OracleSequenceName + ".nextval{SugarSeq:=}";
  232. insertDictionary.Add(item.DbColumnName, value);
  233. continue;
  234. }
  235. else
  236. {
  237. var value = item.PropertyInfo.GetValue(insetObject);
  238. if (value == null&&this.Context.CurrentConnectionConfig.DbType==DbType.PostgreSQL)
  239. {
  240. var underType= UtilMethods.GetUnderType(item.PropertyInfo.PropertyType);
  241. if (underType == UtilConstants.DateType)
  242. {
  243. value = SqlDateTime.Null;
  244. }
  245. }
  246. insertDictionary.Add(item.DbColumnName, value);
  247. }
  248. }
  249. return insertDictionary;
  250. }
  251. private static string GetChildName(SubInsertTreeExpression item, MemberExpression subMemberException)
  252. {
  253. string childName;
  254. MemberExpression listMember = null;
  255. if (subMemberException.Expression is MethodCallExpression)
  256. {
  257. listMember = (subMemberException.Expression as MethodCallExpression).Arguments.First() as MemberExpression;
  258. }
  259. else
  260. {
  261. listMember = (subMemberException.Expression as MemberExpression);
  262. }
  263. if (listMember == null&& item.Expression is LambdaExpression)
  264. {
  265. listMember = (item.Expression as LambdaExpression).Body as MemberExpression;
  266. }
  267. if (listMember == null && item.Expression is MemberExpression)
  268. {
  269. listMember = item.Expression as MemberExpression;
  270. }
  271. childName = listMember.Member.Name;
  272. return childName;
  273. }
  274. private static string GetMemberName(SubInsertTreeExpression item, out MemberExpression subMemberException)
  275. {
  276. string subMemberName = null;
  277. Expression lambdaExpression;
  278. if (item.Expression is LambdaExpression)
  279. {
  280. lambdaExpression = (item.Expression as LambdaExpression).Body;
  281. }
  282. else
  283. {
  284. lambdaExpression = item.Expression;
  285. }
  286. if (lambdaExpression is UnaryExpression)
  287. {
  288. lambdaExpression = (lambdaExpression as UnaryExpression).Operand;
  289. }
  290. subMemberException = lambdaExpression as MemberExpression;
  291. subMemberName = subMemberException.Member.Name;
  292. return subMemberName;
  293. }
  294. private object GetPrimaryKey(EntityInfo entityInfo,object InsertObject, int id)
  295. {
  296. object pkValue;
  297. if (id.ObjToInt() == 0)
  298. {
  299. var primaryProperty = entityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey);
  300. Check.Exception(primaryProperty == null, entityInfo.EntityName + " no primarykey");
  301. pkValue = primaryProperty.PropertyInfo.GetValue(InsertObject);
  302. }
  303. else
  304. {
  305. pkValue = id;
  306. }
  307. return pkValue;
  308. }
  309. }
  310. }