/ControllableQuery/DevBranches/Insert/Source/ControllableQuery/Param.cs

# · C# · 409 lines · 335 code · 74 blank · 0 comment · 0 complexity · 815fd966b712d785bde5df5b08defbb4 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Data.SqlClient;
  5. using PropertyExpression.Common;
  6. namespace PropertyExpression.ControllableQuery
  7. {
  8. public struct Param<T>
  9. {
  10. internal readonly ParamContent<T> Content;
  11. internal Param(ParamContent<T> content)
  12. {
  13. Content = content;
  14. }
  15. public static implicit operator QItem(Param<T> value)
  16. {
  17. return new QItem(builder => builder.Append(value));
  18. }
  19. }
  20. internal class ParamContent<T>
  21. {
  22. internal readonly Func<string, SqlParameter> SqlParameterFunc;
  23. internal readonly Func<T, object> ToSqlParameterValueFunc;
  24. internal readonly Option<Func<T>> ValueFunc;
  25. public ParamContent(Func<string, SqlParameter> sqlParameterFunc, Func<T, object> toSqlParameterValueFunc, Option<Func<T>> valueFunc)
  26. {
  27. SqlParameterFunc = sqlParameterFunc;
  28. ToSqlParameterValueFunc = toSqlParameterValueFunc;
  29. ValueFunc = valueFunc;
  30. }
  31. }
  32. public static class Param
  33. {
  34. public static Param<Guid> New(Guid value)
  35. {
  36. return New(() => value);
  37. }
  38. public static Param<Guid> New(Func<Guid> value)
  39. {
  40. return New(GuidInfo, value);
  41. }
  42. public static Param<Guid> NewGuid()
  43. {
  44. return New(GuidInfo);
  45. }
  46. private static Tuple<Func<string, SqlParameter>, Func<Guid, object>> GuidInfo
  47. {
  48. get { return NewInfo<Guid>(name => new SqlParameter(name, SqlDbType.UniqueIdentifier), _ => _); }
  49. }
  50. public static Param<Option<Guid>> New(Option<Guid> value)
  51. {
  52. return New(() => value);
  53. }
  54. public static Param<Option<Guid>> New(Func<Option<Guid>> value)
  55. {
  56. return New(OptionalGuidInfo, value);
  57. }
  58. public static Param<Option<Guid>> NewOptionalGuid()
  59. {
  60. return New(OptionalGuidInfo);
  61. }
  62. private static Tuple<Func<string, SqlParameter>, Func<Option<Guid>, object>> OptionalGuidInfo
  63. {
  64. get { return NewInfo<Option<Guid>>(name => new SqlParameter(name, SqlDbType.UniqueIdentifier), GetValueOrDbNull); }
  65. }
  66. public static Param<bool> New(bool value)
  67. {
  68. return New(() => value);
  69. }
  70. public static Param<bool> New(Func<bool> value)
  71. {
  72. return New(BoolInfo, value);
  73. }
  74. public static Param<bool> NewBool()
  75. {
  76. return New(BoolInfo);
  77. }
  78. private static Tuple<Func<string, SqlParameter>, Func<bool, object>> BoolInfo
  79. {
  80. get { return NewInfo<bool>(GetBooleanSqlParameterFunc(), _ => _); }
  81. }
  82. public static Param<Option<bool>> New(Option<bool> value)
  83. {
  84. return New(() => value);
  85. }
  86. public static Param<Option<bool>> New(Func<Option<bool>> value)
  87. {
  88. return New(OptionalBool, value);
  89. }
  90. public static Param<Option<bool>> NewOptionalBool()
  91. {
  92. return New(OptionalBool);
  93. }
  94. private static Tuple<Func<string, SqlParameter>, Func<Option<bool>, object>> OptionalBool
  95. {
  96. get { return NewInfo<Option<bool>>(GetBooleanSqlParameterFunc(), GetValueOrDbNull); }
  97. }
  98. public static Param<float> New(float value)
  99. {
  100. return New(() => value);
  101. }
  102. public static Param<float> New(Func<float> value)
  103. {
  104. return New(FloatInfo, value);
  105. }
  106. public static Param<float> NewFloat()
  107. {
  108. return New(FloatInfo);
  109. }
  110. private static Tuple<Func<string, SqlParameter>, Func<float, object>> FloatInfo
  111. {
  112. get { return NewInfo<float>(GetFloatSqlParameterFunc(), _ => _); }
  113. }
  114. public static Param<Option<float>> New(Option<float> value)
  115. {
  116. return New(() => value);
  117. }
  118. public static Param<Option<float>> New(Func<Option<float>> value)
  119. {
  120. return New(OptionalFloatInfo, value);
  121. }
  122. public static Param<Option<float>> NewOptionalFloat()
  123. {
  124. return New(OptionalFloatInfo);
  125. }
  126. private static Tuple<Func<string, SqlParameter>, Func<Option<float>, object>> OptionalFloatInfo
  127. {
  128. get { return NewInfo<Option<float>>(GetFloatSqlParameterFunc(), GetValueOrDbNull); }
  129. }
  130. public static Param<string> New(string value)
  131. {
  132. return New(() => value);
  133. }
  134. public static Param<string> New(Func<string> value)
  135. {
  136. return New(StringInfo, value);
  137. }
  138. public static Param<string> NewString()
  139. {
  140. return New(StringInfo);
  141. }
  142. private static Tuple<Func<string, SqlParameter>, Func<string, object>> StringInfo
  143. {
  144. get { return NewInfo<string>(GetStringSqlParameterFunc(), _ => _); }
  145. }
  146. public static Param<DateTime> New(DateTime value)
  147. {
  148. return New(() => value);
  149. }
  150. public static Param<DateTime> New(Func<DateTime> value)
  151. {
  152. return New(DateTimeInfo, value);
  153. }
  154. public static Param<DateTime> NewDateTime()
  155. {
  156. return New(DateTimeInfo);
  157. }
  158. private static Tuple<Func<string, SqlParameter>, Func<DateTime, object>> DateTimeInfo
  159. {
  160. get { return NewInfo<DateTime>(name => new SqlParameter(name, SqlDbType.DateTime), _ => _); }
  161. }
  162. public static Param<Option<string>> New(Option<string> value)
  163. {
  164. return New(() => value);
  165. }
  166. public static Param<Option<string>> New(Func<Option<string>> value)
  167. {
  168. return New(OptionalStringInfo, value);
  169. }
  170. public static Param<Option<string>> NewOptionalString()
  171. {
  172. return New(OptionalStringInfo);
  173. }
  174. private static Tuple<Func<string, SqlParameter>, Func<Option<string>, object>> OptionalStringInfo
  175. {
  176. get { return NewInfo<Option<string>>(GetStringSqlParameterFunc(), GetValueOrDbNull); }
  177. }
  178. public static Param<int> New(int value)
  179. {
  180. return New(() => value);
  181. }
  182. public static Param<int> New(Func<int> value)
  183. {
  184. return New(IntInfo, value);
  185. }
  186. public static Param<int> NewInt()
  187. {
  188. return New(IntInfo);
  189. }
  190. private static Tuple<Func<string, SqlParameter>, Func<int, object>> IntInfo
  191. {
  192. get { return NewInfo<int>(name => new SqlParameter(name, SqlDbType.Int), _ => _); }
  193. }
  194. public static Param<Option<int>> New(Option<int> value)
  195. {
  196. return New(() => value);
  197. }
  198. public static Param<Option<int>> New(Func<Option<int>> value)
  199. {
  200. return New(OptionalIntInfo, value);
  201. }
  202. public static Param<Option<int>> NewOptionalInt()
  203. {
  204. return New(OptionalIntInfo);
  205. }
  206. private static Tuple<Func<string, SqlParameter>, Func<Option<int>, object>> OptionalIntInfo
  207. {
  208. get { return NewInfo<Option<int>>(name => new SqlParameter(name, SqlDbType.Int), GetValueOrDbNull); }
  209. }
  210. public static Param<ITableValued<T>> New<T>(ITableValued<T> value)
  211. {
  212. return New(() => value);
  213. }
  214. public static Param<ITableValued<T>> New<T>(Func<ITableValued<T>> value)
  215. {
  216. return New(TableValuedInfo<T>(), value);
  217. }
  218. public static Param<ITableValued<T>> NewTableValued<T>()
  219. {
  220. return New(TableValuedInfo<T>());
  221. }
  222. private static Tuple<Func<string, SqlParameter>, Func<ITableValued<T>, object>> TableValuedInfo<T>()
  223. {
  224. return NewInfo<ITableValued<T>>(
  225. parameterName => new SqlParameter(parameterName, SqlDbType.Structured) {
  226. TypeName = typeof (T).Name
  227. },
  228. _ => ConvertToDataTable(_.Value));
  229. }
  230. private static Func<string, SqlParameter> GetFloatSqlParameterFunc()
  231. {
  232. return name => new SqlParameter(name, SqlDbType.Float);
  233. }
  234. private static Func<string, SqlParameter> GetStringSqlParameterFunc()
  235. {
  236. return name => new SqlParameter(name, SqlDbType.NVarChar) { Size = -1 };
  237. }
  238. private static Func<string, SqlParameter> GetBooleanSqlParameterFunc()
  239. {
  240. return name => new SqlParameter(name, SqlDbType.Bit);
  241. }
  242. private static object GetValueOrDbNull<T>(this Option<T> value)
  243. {
  244. return value.Match<object>(_ => _, () => DBNull.Value);
  245. }
  246. private static DataTable ConvertToDataTable<T>(IEnumerable<T> value)
  247. {
  248. var dataTable = new DataTable();
  249. var propertyInfos = typeof(T).GetProperties();
  250. foreach (var propertyInfo in propertyInfos)
  251. {
  252. dataTable.Columns.Add(propertyInfo.Name, propertyInfo.PropertyType);
  253. }
  254. foreach (var item in value)
  255. {
  256. foreach (var propertyInfo in propertyInfos)
  257. {
  258. var dataRow = dataTable.NewRow();
  259. dataRow[propertyInfo.Name] = propertyInfo.GetValue(item, null);
  260. dataTable.Rows.Add(dataRow);
  261. }
  262. }
  263. return dataTable;
  264. }
  265. private static Tuple<Func<string, SqlParameter>, Func<T, object>> NewInfo<T>(
  266. Func<string, SqlParameter> sqlParameterFunc,
  267. Func<T, object> toSqlParameterValueFunc)
  268. {
  269. return Tuple.Create(sqlParameterFunc, toSqlParameterValueFunc);
  270. }
  271. private static Param<T> New<T>(Tuple<Func<string, SqlParameter>, Func<T, object>> tuple)
  272. {
  273. return new Param<T>(new ParamContent<T>(tuple.Item1, tuple.Item2, new Option<Func<T>>()));
  274. }
  275. private static Param<T> New<T>(Tuple<Func<string, SqlParameter>, Func<T, object>> tuple, Func<T> valueFunc)
  276. {
  277. return new Param<T>(new ParamContent<T>(tuple.Item1, tuple.Item2, valueFunc));
  278. }
  279. }
  280. public static class ParamExtensions
  281. {
  282. public static Param<Guid> Param(this Guid value)
  283. {
  284. return ControllableQuery.Param.New(value);
  285. }
  286. public static Param<Option<Guid>> Param(this Option<Guid> value)
  287. {
  288. return ControllableQuery.Param.New(value);
  289. }
  290. public static Param<bool> Param(this bool value)
  291. {
  292. return ControllableQuery.Param.New(value);
  293. }
  294. public static Param<Option<bool>> Param(this Option<bool> value)
  295. {
  296. return ControllableQuery.Param.New(value);
  297. }
  298. public static Param<float> Param(this float value)
  299. {
  300. return ControllableQuery.Param.New(value);
  301. }
  302. public static Param<Option<float>> Param(this Option<float> value)
  303. {
  304. return ControllableQuery.Param.New(value);
  305. }
  306. public static Param<string> Param(this string value)
  307. {
  308. return ControllableQuery.Param.New(value);
  309. }
  310. public static Param<DateTime> Param(this DateTime value)
  311. {
  312. return ControllableQuery.Param.New(value);
  313. }
  314. public static Param<Option<string>> Param(this Option<string> value)
  315. {
  316. return ControllableQuery.Param.New(value);
  317. }
  318. public static Param<int> Param(this int value)
  319. {
  320. return ControllableQuery.Param.New(value);
  321. }
  322. public static Param<Option<int>> Param(this Option<int> value)
  323. {
  324. return ControllableQuery.Param.New(value);
  325. }
  326. public static Param<ITableValued<T>> Param<T>(this ITableValued<T> value)
  327. {
  328. return ControllableQuery.Param.New(value);
  329. }
  330. public static Param<ITableValued<T>> Param<T>(this IEnumerable<T> value)
  331. {
  332. return ControllableQuery.Param.New(value.AsTableValued());
  333. }
  334. }
  335. }