电子药箱通讯服务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SqlMapper.ext.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Reflection.Emit;
  9. using System.Text;
  10. using System.Text.RegularExpressions;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. namespace RDH.Data
  14. {
  15. public static partial class SqlMapper
  16. {
  17. #region 扩展一对多查询
  18. #if !CSHARP30
  19. public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn>(this IDbConnection cnn,
  20. string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn> map,
  21. dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
  22. int? commandTimeout = null, CommandType? commandType = null)
  23. {
  24. return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, DontMap, DontMap, TReturn>(
  25. cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
  26. }
  27. public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn>(this IDbConnection cnn,
  28. string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn> map,
  29. dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
  30. int? commandTimeout = null, CommandType? commandType = null)
  31. {
  32. return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, DontMap, TReturn>(
  33. cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
  34. }
  35. public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(this IDbConnection cnn,
  36. string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn> map,
  37. dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
  38. int? commandTimeout = null, CommandType? commandType = null)
  39. {
  40. return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
  41. cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
  42. }
  43. #endif
  44. static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn>(this IDbConnection cnn,
  45. string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
  46. {
  47. var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, DontMap, DontMap, TReturn>(
  48. cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
  49. return buffered ? results.ToList() : results;
  50. }
  51. static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn>(this IDbConnection cnn,
  52. string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
  53. {
  54. var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, DontMap, TReturn>(cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
  55. return buffered ? results.ToList() : results;
  56. }
  57. static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(this IDbConnection cnn,
  58. string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
  59. {
  60. var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
  61. cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
  62. return buffered ? results.ToList() : results;
  63. }
  64. internal static IEnumerable<TReturn> MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
  65. this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, string splitOn, int? commandTimeout,
  66. CommandType? commandType, IDataReader reader, Identity identity)
  67. {
  68. identity = identity ?? new Identity(sql, commandType, cnn, typeof(TFirst),
  69. (object)param == null ? null : ((object)param).GetType(),
  70. new[]
  71. {
  72. typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh), typeof(TEighth),
  73. typeof(TNinth), typeof(TTenth)
  74. });
  75. CacheInfo cinfo = GetCacheInfo(identity);
  76. IDbCommand ownedCommand = null;
  77. IDataReader ownedReader = null;
  78. try
  79. {
  80. if (reader == null)
  81. {
  82. ownedCommand = SetupCommand(cnn, transaction, sql, cinfo.ParamReader, (object)param, commandTimeout, commandType);
  83. ownedReader = ownedCommand.ExecuteReader();
  84. reader = ownedReader;
  85. }
  86. Func<IDataReader, object> deserializer = null;
  87. Func<IDataReader, object>[] otherDeserializers = null;
  88. Action cacheDeserializers = () =>
  89. {
  90. var deserializers = GenerateDeserializers(new Type[]
  91. {
  92. typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh), typeof(TEighth),
  93. typeof(TNinth), typeof(TTenth)
  94. }, splitOn, reader);
  95. deserializer = cinfo.Deserializer = deserializers[0];
  96. otherDeserializers = cinfo.OtherDeserializers = deserializers.Skip(1).ToArray();
  97. SetQueryCache(identity, cinfo);
  98. };
  99. if ((deserializer = cinfo.Deserializer) == null || (otherDeserializers = cinfo.OtherDeserializers) == null)
  100. {
  101. cacheDeserializers();
  102. }
  103. Func<IDataReader, TReturn> mapIt = GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
  104. deserializer, otherDeserializers, map);
  105. if (mapIt != null)
  106. {
  107. while (reader.Read())
  108. {
  109. TReturn next;
  110. try
  111. {
  112. next = mapIt(reader);
  113. }
  114. catch (DataException)
  115. {
  116. cacheDeserializers();
  117. mapIt = GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
  118. deserializer, otherDeserializers, map);
  119. next = mapIt(reader);
  120. }
  121. yield return next;
  122. }
  123. }
  124. }
  125. finally
  126. {
  127. try
  128. {
  129. if (ownedReader != null)
  130. {
  131. ownedReader.Dispose();
  132. }
  133. }
  134. finally
  135. {
  136. if (ownedCommand != null)
  137. {
  138. ownedCommand.Dispose();
  139. }
  140. }
  141. }
  142. }
  143. private static Func<IDataReader, TReturn> GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
  144. Func<IDataReader, object> deserializer, Func<IDataReader, object>[] otherDeserializers, object map)
  145. {
  146. switch (otherDeserializers.Length)
  147. {
  148. case 1:
  149. return r => ((Func<TFirst, TSecond, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r));
  150. case 2:
  151. return r => ((Func<TFirst, TSecond, TThird, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r));
  152. case 3:
  153. return r => ((Func<TFirst, TSecond, TThird, TFourth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r));
  154. #if !CSHARP30
  155. case 4:
  156. return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r));
  157. #endif
  158. case 5:
  159. return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r));
  160. case 6:
  161. return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r));
  162. case 7:
  163. return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn>)map)(
  164. (TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r),
  165. (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r), (TEighth)otherDeserializers[6](r));
  166. case 8:
  167. return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn>)map)(
  168. (TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r),
  169. (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r), (TEighth)otherDeserializers[6](r),
  170. (TNinth)otherDeserializers[7](r));
  171. case 9:
  172. return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>)map)(
  173. (TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r),
  174. (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r), (TEighth)otherDeserializers[6](r),
  175. (TNinth)otherDeserializers[7](r), (TTenth)otherDeserializers[8](r));
  176. default:
  177. throw new NotSupportedException();
  178. }
  179. }
  180. #endregion
  181. }
  182. }