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.

SqlServerManager.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.Entity;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using iiie.Logs.DBO;
  7. using iiie.WebApiUtils.DBO;
  8. namespace iiie.WebApiUtils.BusinessManager
  9. {
  10. /// <summary>
  11. /// Helper for SQL Server data access
  12. /// </summary>
  13. public abstract class SqlServerManager<TDbObject, TDboGet, TDboAdd, TDboEdit, TEntities, TThis>
  14. : SqlServerBasicManager<TDbObject, TEntities, TThis>
  15. where TDbObject : class
  16. where TEntities : DbContext, new()
  17. where TThis : SqlServerManager<TDbObject, TDboGet, TDboAdd, TDboEdit, TEntities, TThis>, new()
  18. {
  19. /// <summary>
  20. /// Convert a DB object to DBO
  21. /// </summary>
  22. /// <param name="obj">The object to be converted</param>
  23. /// <returns>The DBO</returns>
  24. public abstract TDboGet DbToDboGet(TDbObject obj);
  25. /// <summary>
  26. /// Convert a DBO to DB object
  27. /// </summary>
  28. /// <param name="obj">The object to be converted</param>
  29. /// <returns>The DB object</returns>
  30. public abstract OpResult<TDbObject> DboAddToDb(TDboAdd obj);
  31. /// <summary>
  32. /// Convert a DBO to DB object
  33. /// </summary>
  34. /// <param name="obj">The object to be converted</param>
  35. /// <param name="edit">The object beeing edited</param>
  36. /// <returns>The DB object</returns>
  37. public abstract OpResult<TDbObject> DboEditToDb(TDboEdit obj, TDbObject edit);
  38. /// <summary>
  39. /// Helper to convert DB object to DBO
  40. /// </summary>
  41. /// <param name="res">The result to convert</param>
  42. /// <returns>The DBO object</returns>
  43. public static TDboGet DbToDboGetStatic(TDbObject res)
  44. {
  45. var obj = new TThis();
  46. return obj.DbToDboGet(res);
  47. }
  48. /// <summary>
  49. /// Helper to convert DBO object to DB
  50. /// </summary>
  51. /// <param name="res">The result to convert</param>
  52. /// <returns>The DB object</returns>
  53. public static OpResult<TDbObject> DboAddToDbStatic(TDboAdd res)
  54. {
  55. var obj = new TThis();
  56. return obj.DboAddToDb(res);
  57. }
  58. /// <summary>
  59. /// Helper to convert DBO object to DB
  60. /// </summary>
  61. /// <param name="res">The result to convert</param>
  62. /// <param name="edit">The object beeing edited</param>
  63. /// <returns>The DB object</returns>
  64. public static OpResult<TDbObject> DboEditToDbStatic(TDboEdit res, TDbObject edit)
  65. {
  66. var obj = new TThis();
  67. return obj.DboEditToDb(res, edit);
  68. }
  69. /// <summary>
  70. /// Get a single DB object matching the predicate
  71. /// </summary>
  72. /// <param name="table">The table to search in</param>
  73. /// <param name="predicate">The predicate</param>
  74. /// <returns>The object that match</returns>
  75. public static OpResult<TDbObject> GetSingleDbObject(DbSet<TDbObject> table, Expression<Func<TDbObject, bool>> predicate)
  76. {
  77. var o = table.FirstOrDefault(predicate);
  78. if (o == null)
  79. {
  80. return OpResult<TDbObject>.Error(ResultStatus.NotFound, typeof(TThis).Name + ": Value not found", "");
  81. }
  82. return OpResult<TDbObject>.Ok(o);
  83. }
  84. /// <summary>
  85. /// Get a single DBO matching the predicate
  86. /// </summary>
  87. /// <param name="predicate">The predicate</param>
  88. /// <returns>The object that match, or null</returns>
  89. public static OpResult<TDboGet> GetSingle(Expression<Func<TDbObject, bool>> predicate)
  90. {
  91. return Execute((db, table) =>
  92. {
  93. var obj = GetSingleDbObject(table, predicate);
  94. if (!obj)
  95. return obj.To<TDboGet>();
  96. return OpResult<TDboGet>.Ok(DbToDboGetStatic(obj.Data));
  97. });
  98. }
  99. /// <summary>
  100. /// Get an object by its primary key(s)
  101. /// </summary>
  102. /// <param name="keys">The key names and values</param>
  103. /// <returns>The object</returns>
  104. public static OpResult<TDboGet> GetSingleByKeys(params KeyValuePair<string, object>[] keys)
  105. {
  106. return GetSingle(GetExpression(keys));
  107. }
  108. /// <summary>
  109. /// Get an object by its id
  110. /// </summary>
  111. /// <param name="id">The id of the object</param>
  112. /// <returns>The object</returns>
  113. public static OpResult<TDboGet> GetSingleById(long id)
  114. {
  115. return GetSingleByKeys(new KeyValuePair<string, object>("id", id));
  116. }
  117. /// <summary>
  118. /// Get all DB object matching the predicate
  119. /// </summary>
  120. /// <param name="predicate">The predicate</param>
  121. /// <param name="orderBy">The order by function</param>
  122. /// <param name="page">The page numeber (0 based)</param>
  123. /// <param name="perPage">The maximum number of items par page</param>
  124. /// <returns>All matching objects</returns>
  125. public static OpResult<DboGetMultiple<TDboGet>> GetMultiple<TKey>(Expression<Func<TDbObject, bool>> predicate,
  126. Expression<Func<TDbObject, TKey>> orderBy, int page = 0, int perPage = Int32.MaxValue)
  127. {
  128. return Execute((db, table) =>
  129. {
  130. var count = table.Count(predicate);
  131. var results = table.OrderBy(orderBy).Where(predicate).Skip(page * perPage).Take(perPage).Select(DbToDboGetStatic).ToList();
  132. var result = new DboGetMultiple<TDboGet>
  133. {
  134. Count = count,
  135. Data = results
  136. };
  137. return OpResult<DboGetMultiple<TDboGet>>.Ok(result);
  138. });
  139. }
  140. /// <summary>
  141. /// Get all DB object matching the predicate built from keys
  142. /// </summary>
  143. /// <param name="page">The page numeber (0 based)</param>
  144. /// <param name="perPage">The maximum number of items par page</param>
  145. /// <param name="orderBy">The order by function</param>
  146. /// <param name="keys">The key names and values</param>
  147. /// <returns>All matching objects</returns>
  148. public static OpResult<DboGetMultiple<TDboGet>> GetMultipleByKeys<TKey>(Expression<Func<TDbObject, TKey>> orderBy,
  149. int page = 0, int perPage = Int32.MaxValue, params KeyValuePair<string, object>[] keys)
  150. {
  151. return GetMultiple(GetExpression(keys), orderBy, page, perPage);
  152. }
  153. /// <summary>
  154. /// Add an entry in the database
  155. /// </summary>
  156. /// <param name="obj">The object to be added</param>
  157. /// <param name="returnFunc">Used to return some data</param>
  158. /// <returns>The result defined by returnFunc</returns>
  159. public static OpResult<T> Add<T>(TDboAdd obj, Expression<Func<TDbObject, T>> returnFunc)
  160. {
  161. return Execute((db, table) =>
  162. {
  163. var item = DboAddToDbStatic(obj);
  164. if (!item)
  165. return item.To<T>();
  166. table.Add(item.Data);
  167. db.SaveChanges();
  168. var res = returnFunc.Compile().DynamicInvoke(item.Data);
  169. return OpResult<T>.Ok((T)res);
  170. });
  171. }
  172. /// <summary>
  173. /// Add an entry in the database
  174. /// </summary>
  175. /// <param name="obj">The object to be added</param>
  176. /// <returns>Always true or an OpResult error</returns>
  177. public static OpResult<bool> Add(TDboAdd obj)
  178. {
  179. return Add(obj, x => true);
  180. }
  181. /// <summary>
  182. /// Add an entry in the database
  183. /// </summary>
  184. /// <param name="obj">The object to be added</param>
  185. /// <returns>The DBO or an OpResult error</returns>
  186. public static OpResult<TDboGet> AddDbo(TDboAdd obj)
  187. {
  188. return Add(obj, x => DbToDboGetStatic(x));
  189. }
  190. /// <summary>
  191. /// Add an entry in the database
  192. /// </summary>
  193. /// <param name="obj">The object to be added</param>
  194. /// <returns>The DBO or an OpResult error</returns>
  195. public static OpResult<long> AddId(TDboAdd obj)
  196. {
  197. var param = Expression.Parameter(typeof(TDbObject), "x");
  198. var exp = Expression.Property(param, "id");
  199. var lambda = Expression.Lambda<Func<TDbObject, long>>(exp, param);
  200. return Add(obj, lambda);
  201. }
  202. /// <summary>
  203. /// Edit an entry in the database
  204. /// </summary>
  205. /// <param name="obj">The object to be added</param>
  206. /// <param name="predicate">The predicate to be used to select data</param>
  207. /// <returns>Always true or an OpResult error</returns>
  208. public static OpResult<bool> Edit(TDboEdit obj, Expression<Func<TDbObject, bool>> predicate)
  209. {
  210. return Execute((db, table) =>
  211. {
  212. var edit = GetSingleDbObject(table, predicate);
  213. if (!edit)
  214. return edit.To<bool>();
  215. var res = DboEditToDbStatic(obj, edit.Data);
  216. if (!res)
  217. return res.To<bool>();
  218. db.Entry(edit.Data).CurrentValues.SetValues(res.Data);
  219. db.SaveChanges();
  220. return OpResult<bool>.Ok(true);
  221. });
  222. }
  223. /// <summary>
  224. /// Edit an entry in the database
  225. /// </summary>
  226. /// <param name="obj">The object to be added</param>
  227. /// <param name="keys">The keys to be used to select data</param>
  228. /// <returns>Always true or an OpResult error</returns>
  229. public static OpResult<bool> Edit(TDboEdit obj, params KeyValuePair<string, object>[] keys)
  230. {
  231. return Edit(obj, GetExpression(keys));
  232. }
  233. /// <summary>
  234. /// Edit an entry in the database
  235. /// </summary>
  236. /// <param name="obj">The object to be added</param>
  237. /// <param name="id">The id to be edited</param>
  238. /// <returns>Always true or an OpResult error</returns>
  239. public static OpResult<bool> EditById(TDboEdit obj, long id)
  240. {
  241. return Edit(obj, new KeyValuePair<string, object>("id", id));
  242. }
  243. /// <summary>
  244. /// Delete an entry in the database
  245. /// </summary>
  246. /// <param name="predicate">The predicate to be used to delete data</param>
  247. /// <returns>Always true or an OpResult error</returns>
  248. public static OpResult<bool> Delete(Expression<Func<TDbObject, bool>> predicate)
  249. {
  250. return Execute((db, table) =>
  251. {
  252. var del = GetSingleDbObject(table, predicate);
  253. if (!del)
  254. return del.To<bool>();
  255. table.Remove(del.Data);
  256. db.SaveChanges();
  257. return OpResult<bool>.Ok(true);
  258. });
  259. }
  260. /// <summary>
  261. /// Delete an entry in the database
  262. /// </summary>
  263. /// <param name="keys">The keys to be used to delete data</param>
  264. /// <returns>Always true or an OpResult error</returns>
  265. public static OpResult<bool> Delete(params KeyValuePair<string, object>[] keys)
  266. {
  267. return Delete(GetExpression(keys));
  268. }
  269. /// <summary>
  270. /// Delete an entry in the database
  271. /// </summary>
  272. /// <param name="id">The id to be deleted</param>
  273. /// <returns>Always true or an OpResult error</returns>
  274. public static OpResult<bool> DeleteById(long id)
  275. {
  276. return Delete(new KeyValuePair<string, object>("id", id));
  277. }
  278. }
  279. }