PageRenderTime 64ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 1ms

/ExpenseTracker.Repository/ExpenseTrackerRepository.cs

https://gitlab.com/arif2009/Building-and-Securing-a-RESTful-API-for-Multiple-Clients-in-ASP.NET
C# | 299 lines | 207 code | 61 blank | 31 comment | 35 complexity | 724ed7059a1892488b1599987de57afe MD5 | raw file
  1. using ExpenseTracker.Repository.Entities;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data.Entity;
  5. using System.Data.Entity.Infrastructure;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace ExpenseTracker.Repository
  10. {
  11. public class ExpenseTrackerEFRepository : IExpenseTrackerRepository
  12. {
  13. // TODO: in a later stage, everything must be user-specific, eg: the
  14. // userid must always be passed in! Don't do this in the first stage,
  15. // this allows us to show what can go wrong if you don't include the
  16. // user check.
  17. ExpenseTrackerContext _ctx;
  18. public ExpenseTrackerEFRepository(ExpenseTrackerContext ctx)
  19. {
  20. _ctx = ctx;
  21. // Disable lazy loading - if not, related properties are auto-loaded when
  22. // they are accessed for the first time, which means they'll be included when
  23. // we serialize (b/c the serialization process accesses those properties).
  24. //
  25. // We don't want that, so we turn it off. We want to eagerly load them (using Include)
  26. // manually.
  27. _ctx.Configuration.LazyLoadingEnabled = false;
  28. }
  29. public Expense GetExpense(int id, int? expenseGroupId = null)
  30. {
  31. return _ctx.Expenses.FirstOrDefault(e => e.Id == id &&
  32. (expenseGroupId == null || expenseGroupId == e.ExpenseGroupId));
  33. }
  34. public IQueryable<Expense> GetExpenses(int expenseGroupId)
  35. {
  36. // if the expense group exists, we return the expenses for that group.
  37. // if it doesn't exist, we return null, so we can throw a not found exception
  38. var correctGroup = _ctx.ExpenseGroups.FirstOrDefault(eg => eg.Id == expenseGroupId);
  39. if (correctGroup != null)
  40. {
  41. return _ctx.Expenses.Where(e => e.ExpenseGroupId == expenseGroupId);
  42. }
  43. else
  44. {
  45. return null;
  46. }
  47. }
  48. public IQueryable<Expense> GetExpenses()
  49. {
  50. return _ctx.Expenses;
  51. }
  52. public ExpenseGroup GetExpenseGroup(int id)
  53. {
  54. return _ctx.ExpenseGroups.FirstOrDefault(eg => eg.Id == id);
  55. }
  56. public ExpenseGroup GetExpenseGroup(int id, string userId)
  57. {
  58. return _ctx.ExpenseGroups.FirstOrDefault(eg => eg.Id == id && eg.UserId == userId);
  59. }
  60. public ExpenseGroup GetExpenseGroupWithExpenses(int id, string userId)
  61. {
  62. return _ctx.ExpenseGroups.Include("Expenses").FirstOrDefault(eg => eg.Id == id && eg.UserId == userId);
  63. }
  64. public ExpenseGroup GetExpenseGroupWithExpenses(int id)
  65. {
  66. return _ctx.ExpenseGroups.Include("Expenses").FirstOrDefault(eg => eg.Id == id);
  67. }
  68. public IQueryable<ExpenseGroup> GetExpenseGroups()
  69. {
  70. return _ctx.ExpenseGroups;
  71. }
  72. public IQueryable<ExpenseGroup> GetExpenseGroupsWithExpenses()
  73. {
  74. return _ctx.ExpenseGroups.Include("Expenses");
  75. }
  76. public IQueryable<ExpenseGroup> GetExpenseGroups(string userId)
  77. {
  78. return _ctx.ExpenseGroups.Where(eg => eg.UserId == userId);
  79. }
  80. public ExpenseGroupStatus GetExpenseGroupStatus(int id)
  81. {
  82. return _ctx.ExpenseGroupStatusses.FirstOrDefault(egs => egs.Id == id);
  83. }
  84. public IQueryable<ExpenseGroupStatus> GetExpenseGroupStatusses()
  85. {
  86. return _ctx.ExpenseGroupStatusses;
  87. }
  88. /// <summary>
  89. /// Return bool if ok, the newly-created ExpenseGroup is still available (including
  90. /// the id) to the calling class.
  91. /// </summary>
  92. /// <param name="eg"></param>
  93. /// <returns></returns>
  94. public RepositoryActionResult<ExpenseGroup> InsertExpenseGroup(ExpenseGroup eg)
  95. {
  96. try
  97. {
  98. _ctx.ExpenseGroups.Add(eg);
  99. var result = _ctx.SaveChanges();
  100. if (result > 0)
  101. {
  102. return new RepositoryActionResult<ExpenseGroup>(eg, RepositoryActionStatus.Created);
  103. }
  104. else
  105. {
  106. return new RepositoryActionResult<ExpenseGroup>(eg, RepositoryActionStatus.NothingModified, null);
  107. }
  108. }
  109. catch (Exception ex)
  110. {
  111. return new RepositoryActionResult<ExpenseGroup>(null, RepositoryActionStatus.Error, ex);
  112. }
  113. }
  114. public RepositoryActionResult<Expense> InsertExpense(Expense e)
  115. {
  116. try
  117. {
  118. _ctx.Expenses.Add(e);
  119. var result = _ctx.SaveChanges();
  120. if (result > 0)
  121. {
  122. return new RepositoryActionResult<Expense>(e, RepositoryActionStatus.Created);
  123. }
  124. else
  125. {
  126. return new RepositoryActionResult<Expense>(e, RepositoryActionStatus.NothingModified, null);
  127. }
  128. }
  129. catch (Exception ex)
  130. {
  131. return new RepositoryActionResult<Expense>(null, RepositoryActionStatus.Error, ex);
  132. }
  133. }
  134. public RepositoryActionResult<ExpenseGroup> UpdateExpenseGroup(ExpenseGroup eg)
  135. {
  136. try
  137. {
  138. // you can only update when an expensegroup already exists for this id
  139. var existingEG = _ctx.ExpenseGroups.FirstOrDefault(exg => exg.Id == eg.Id);
  140. if (existingEG == null)
  141. {
  142. return new RepositoryActionResult<ExpenseGroup>(eg, RepositoryActionStatus.NotFound);
  143. }
  144. // change the original entity status to detached; otherwise, we get an error on attach
  145. // as the entity is already in the dbSet
  146. // set original entity state to detached
  147. _ctx.Entry(existingEG).State = EntityState.Detached;
  148. // attach & save
  149. _ctx.ExpenseGroups.Attach(eg);
  150. // set the updated entity state to modified, so it gets updated.
  151. _ctx.Entry(eg).State = EntityState.Modified;
  152. var result = _ctx.SaveChanges();
  153. if (result > 0)
  154. {
  155. return new RepositoryActionResult<ExpenseGroup>(eg, RepositoryActionStatus.Updated);
  156. }
  157. else
  158. {
  159. return new RepositoryActionResult<ExpenseGroup>(eg, RepositoryActionStatus.NothingModified, null);
  160. }
  161. }
  162. catch (Exception ex)
  163. {
  164. return new RepositoryActionResult<ExpenseGroup>(null, RepositoryActionStatus.Error, ex);
  165. }
  166. }
  167. public RepositoryActionResult<Expense> UpdateExpense(Expense e)
  168. {
  169. try
  170. {
  171. // you can only update when an expense already exists for this id
  172. var existingExpense = _ctx.Expenses.FirstOrDefault(exp => exp.Id == e.Id);
  173. if (existingExpense == null)
  174. {
  175. return new RepositoryActionResult<Expense>(e, RepositoryActionStatus.NotFound);
  176. }
  177. // change the original entity status to detached; otherwise, we get an error on attach
  178. // as the entity is already in the dbSet
  179. // set original entity state to detached
  180. _ctx.Entry(existingExpense).State = EntityState.Detached;
  181. // attach & save
  182. _ctx.Expenses.Attach(e);
  183. // set the updated entity state to modified, so it gets updated.
  184. _ctx.Entry(e).State = EntityState.Modified;
  185. var result = _ctx.SaveChanges();
  186. if (result > 0)
  187. {
  188. return new RepositoryActionResult<Expense>(e, RepositoryActionStatus.Updated);
  189. }
  190. else
  191. {
  192. return new RepositoryActionResult<Expense>(e, RepositoryActionStatus.NothingModified, null);
  193. }
  194. }
  195. catch (Exception ex)
  196. {
  197. return new RepositoryActionResult<Expense>(null, RepositoryActionStatus.Error, ex);
  198. }
  199. }
  200. public RepositoryActionResult<Expense> DeleteExpense(int id)
  201. {
  202. try
  203. {
  204. var exp = _ctx.Expenses.Where(e => e.Id == id).FirstOrDefault();
  205. if (exp != null)
  206. {
  207. _ctx.Expenses.Remove(exp);
  208. _ctx.SaveChanges();
  209. return new RepositoryActionResult<Expense>(null, RepositoryActionStatus.Deleted);
  210. }
  211. return new RepositoryActionResult<Expense>(null, RepositoryActionStatus.NotFound);
  212. }
  213. catch (Exception ex)
  214. {
  215. return new RepositoryActionResult<Expense>(null, RepositoryActionStatus.Error, ex);
  216. }
  217. }
  218. public RepositoryActionResult<ExpenseGroup> DeleteExpenseGroup(int id)
  219. {
  220. try
  221. {
  222. var eg = _ctx.ExpenseGroups.Where(e => e.Id == id).FirstOrDefault();
  223. if (eg != null)
  224. {
  225. // also remove all expenses linked to this expensegroup
  226. _ctx.ExpenseGroups.Remove(eg);
  227. _ctx.SaveChanges();
  228. return new RepositoryActionResult<ExpenseGroup>(null, RepositoryActionStatus.Deleted);
  229. }
  230. return new RepositoryActionResult<ExpenseGroup>(null, RepositoryActionStatus.NotFound);
  231. }
  232. catch (Exception ex)
  233. {
  234. return new RepositoryActionResult<ExpenseGroup>(null, RepositoryActionStatus.Error, ex);
  235. }
  236. }
  237. }
  238. }