PageRenderTime 27ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/Backup/SubSonic.Core/Repository/SimpleRepository.cs

https://bitbucket.org/moisesmiranda/subsonic-4
C# | 331 lines | 195 code | 45 blank | 91 comment | 21 complexity | 90e89c3acc2c0909725ab0a280383967 MD5 | raw file
  1. //
  2. // SubSonic - http://subsonicproject.com
  3. //
  4. // The contents of this file are subject to the New BSD
  5. // License (the "License"); you may not use this file
  6. // except in compliance with the License. You may obtain a copy of
  7. // the License at http://www.opensource.org/licenses/bsd-license.php
  8. //
  9. // Software distributed under the License is distributed on an
  10. // "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11. // implied. See the License for the specific language governing
  12. // rights and limitations under the License.
  13. //
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Linq.Expressions;
  18. using System.Reflection;
  19. using SubSonic.Extensions;
  20. using SubSonic.DataProviders;
  21. using SubSonic.Query;
  22. using SubSonic.Schema;
  23. using SubSonic.Linq.Structure;
  24. namespace SubSonic.Repository
  25. {
  26. public class SimpleRepository : IRepository
  27. {
  28. private readonly IDataProvider _provider;
  29. private readonly List<Type> migrated;
  30. private readonly SimpleRepositoryOptions _options=SimpleRepositoryOptions.Default;
  31. public SimpleRepository() : this(ProviderFactory.GetProvider(),SimpleRepositoryOptions.Default) {}
  32. public SimpleRepository(string connectionStringName)
  33. : this(connectionStringName,SimpleRepositoryOptions.Default) { }
  34. public SimpleRepository(string connectionStringName, SimpleRepositoryOptions options)
  35. : this(ProviderFactory.GetProvider(connectionStringName), options) { }
  36. public SimpleRepository(SimpleRepositoryOptions options) : this(ProviderFactory.GetProvider(), options) { }
  37. public SimpleRepository(IDataProvider provider) : this(provider, SimpleRepositoryOptions.Default) {}
  38. public SimpleRepository(IDataProvider provider, SimpleRepositoryOptions options)
  39. {
  40. _provider = provider;
  41. _options = options;
  42. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  43. migrated = new List<Type>();
  44. }
  45. #region IRepository Members
  46. public bool Exists<T>(Expression<Func<T, bool>> expression) where T : class, new()
  47. {
  48. return All<T>().Any(expression);
  49. }
  50. public IQueryable<T> All<T>() where T : class, new()
  51. {
  52. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  53. Migrate<T>();
  54. var qry = new Query<T>(_provider);
  55. return qry;
  56. }
  57. /// <summary>
  58. /// Singles the specified expression.
  59. /// </summary>
  60. /// <typeparam name="T"></typeparam>
  61. /// <param name="expression">The expression.</param>
  62. /// <returns></returns>
  63. public T Single<T>(Expression<Func<T, bool>> expression) where T : class, new()
  64. {
  65. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  66. Migrate<T>();
  67. T result = default(T);
  68. var tbl = _provider.FindOrCreateTable<T>();
  69. var qry = new Select(_provider).From(tbl);
  70. var constraints = expression.ParseConstraints().ToList();
  71. qry.Constraints = constraints;
  72. var list = qry.ToList<T>();
  73. if(list.Count > 0)
  74. result = list[0];
  75. return result;
  76. }
  77. /// <summary>
  78. /// Singles the specified key.
  79. /// </summary>
  80. /// <typeparam name="T"></typeparam>
  81. /// <param name="key">The key.</param>
  82. /// <returns></returns>
  83. public T Single<T>(object key) where T : class, new()
  84. {
  85. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  86. Migrate<T>();
  87. var tbl = _provider.FindOrCreateTable<T>();
  88. var result = new Select(_provider).From(tbl).Where(tbl.PrimaryKey).IsEqualTo(key).ExecuteSingle<T>();
  89. return result;
  90. }
  91. /// <summary>
  92. /// Retrieves subset of records from the database matching the expression
  93. /// </summary>
  94. public IList<T> Find<T>(Expression<Func<T, bool>> expression) where T : class, new()
  95. {
  96. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  97. Migrate<T>();
  98. var tbl = _provider.FindOrCreateTable<T>();
  99. var qry = new Select(_provider).From(tbl);
  100. var constraints = expression.ParseConstraints().ToList();
  101. qry.Constraints = constraints;
  102. return qry.ExecuteTypedList<T>();
  103. }
  104. /// <summary>
  105. /// Gets the paged.
  106. /// </summary>
  107. /// <typeparam name="T"></typeparam>
  108. /// <param name="pageIndex">Index of the page.</param>
  109. /// <param name="pageSize">Size of the page.</param>
  110. /// <returns></returns>
  111. public PagedList<T> GetPaged<T>(int pageIndex, int pageSize) where T : class, new()
  112. {
  113. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  114. Migrate<T>();
  115. var tbl = _provider.FindOrCreateTable<T>();
  116. var qry = new Select(_provider).From(tbl).Paged(pageIndex + 1, pageSize).OrderAsc(tbl.PrimaryKey.Name);
  117. var total =
  118. new Select(_provider, new Aggregate(tbl.PrimaryKey, AggregateFunction.Count)).From<T>().ExecuteScalar();
  119. int totalRecords = 0;
  120. int.TryParse(total.ToString(), out totalRecords);
  121. return new PagedList<T>(qry.ToList<T>(), totalRecords, pageIndex, pageSize);
  122. }
  123. /// <summary>
  124. /// Gets the paged.
  125. /// </summary>
  126. /// <typeparam name="T"></typeparam>
  127. /// <param name="sortBy">The sort by.</param>
  128. /// <param name="pageIndex">Index of the page.</param>
  129. /// <param name="pageSize">Size of the page.</param>
  130. /// <returns></returns>
  131. public PagedList<T> GetPaged<T>(string sortBy, int pageIndex, int pageSize) where T : class, new()
  132. {
  133. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  134. Migrate<T>();
  135. var tbl = _provider.FindOrCreateTable<T>();
  136. var qry = new Select(_provider).From(tbl).Paged(pageIndex + 1, pageSize).OrderAsc(sortBy);
  137. var total =
  138. new Select(_provider, new Aggregate(tbl.PrimaryKey, AggregateFunction.Count)).From<T>().ExecuteScalar();
  139. return new PagedList<T>(qry.ToList<T>(), (int)total, pageIndex, pageSize);
  140. }
  141. /// <summary>
  142. /// Adds the specified item, setting the key if available.
  143. /// </summary>
  144. /// <typeparam name="T"></typeparam>
  145. /// <param name="item">The item.</param>
  146. /// <returns></returns>
  147. public object Add<T>(T item) where T : class, new()
  148. {
  149. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  150. Migrate<T>();
  151. object result = null;
  152. using(var rdr = item.ToInsertQuery(_provider).ExecuteReader())
  153. {
  154. if(rdr.Read())
  155. result = rdr[0];
  156. }
  157. //for Rick :)
  158. if (result != null && result != DBNull.Value) {
  159. try {
  160. var tbl = _provider.FindOrCreateTable(typeof(T));
  161. var prop = item.GetType().GetProperty(tbl.PrimaryKey.Name);
  162. var settable = result.ChangeTypeTo(prop.PropertyType);
  163. prop.SetValue(item, settable, null);
  164. } catch(Exception x) {
  165. //swallow it - I don't like this per se but this is a convenience and we
  166. //don't want to throw the whole thing just because we can't auto-set the value
  167. }
  168. }
  169. return result;
  170. }
  171. /// <summary>
  172. /// Adds a lot of the items using a transaction.
  173. /// </summary>
  174. /// <typeparam name="T"></typeparam>
  175. /// <param name="items">The items.</param>
  176. public void AddMany<T>(IEnumerable<T> items) where T : class, new()
  177. {
  178. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  179. Migrate<T>();
  180. BatchQuery batch = new BatchQuery(_provider);
  181. foreach(var item in items)
  182. batch.QueueForTransaction(item.ToInsertQuery(_provider));
  183. batch.ExecuteTransaction();
  184. }
  185. /// <summary>
  186. /// Updates the specified item.
  187. /// </summary>
  188. /// <typeparam name="T"></typeparam>
  189. /// <param name="item">The item.</param>
  190. /// <returns></returns>
  191. public int Update<T>(T item) where T : class, new()
  192. {
  193. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  194. Migrate<T>();
  195. return item.ToUpdateQuery(_provider).Execute();
  196. }
  197. /// <summary>
  198. /// Updates lots of items using a transaction.
  199. /// </summary>
  200. /// <typeparam name="T"></typeparam>
  201. /// <param name="items">The items.</param>
  202. /// <returns></returns>
  203. public int UpdateMany<T>(IEnumerable<T> items) where T : class, new()
  204. {
  205. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  206. Migrate<T>();
  207. BatchQuery batch = new BatchQuery(_provider);
  208. int result = 0;
  209. foreach(var item in items)
  210. {
  211. batch.QueueForTransaction(item.ToUpdateQuery(_provider));
  212. result++;
  213. }
  214. batch.ExecuteTransaction();
  215. return result;
  216. }
  217. /// <summary>
  218. /// Deletes the specified key.
  219. /// </summary>
  220. /// <typeparam name="T"></typeparam>
  221. /// <param name="key">The key.</param>
  222. /// <returns></returns>
  223. public int Delete<T>(object key) where T : class, new()
  224. {
  225. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  226. Migrate<T>();
  227. var tbl = _provider.FindOrCreateTable<T>();
  228. return new Delete<T>(_provider).From<T>().Where(tbl.PrimaryKey).IsEqualTo(key).Execute();
  229. }
  230. /// <summary>
  231. /// Deletes 1 or more items.
  232. /// </summary>
  233. /// <typeparam name="T"></typeparam>
  234. /// <param name="expression">The expression.</param>
  235. /// <returns></returns>
  236. public int DeleteMany<T>(Expression<Func<T, bool>> expression) where T : class, new()
  237. {
  238. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  239. Migrate<T>();
  240. var tbl = _provider.FindOrCreateTable<T>();
  241. var qry = new Delete<T>(_provider).From<T>();
  242. var constraints = expression.ParseConstraints().ToList();
  243. qry.Constraints = constraints;
  244. return qry.Execute();
  245. }
  246. /// <summary>
  247. /// Deletes 1 or more items.
  248. /// </summary>
  249. /// <typeparam name="T"></typeparam>
  250. /// <param name="items">The items.</param>
  251. /// <returns></returns>
  252. public int DeleteMany<T>(IEnumerable<T> items) where T : class, new()
  253. {
  254. if (_options.Contains(SimpleRepositoryOptions.RunMigrations))
  255. Migrate<T>();
  256. BatchQuery batch = new BatchQuery(_provider);
  257. int result = 0;
  258. foreach(var item in items)
  259. {
  260. batch.QueueForTransaction(item.ToDeleteQuery(_provider));
  261. result++;
  262. }
  263. batch.ExecuteTransaction();
  264. return result;
  265. }
  266. #endregion
  267. /// <summary>
  268. /// Migrates this instance.
  269. /// </summary>
  270. /// <typeparam name="T"></typeparam>
  271. private void Migrate<T>() where T : class, new()
  272. {
  273. Type type = typeof(T);
  274. if(!migrated.Contains(type))
  275. {
  276. BatchQuery batch = new BatchQuery(_provider);
  277. Migrator m = new Migrator(Assembly.GetExecutingAssembly());
  278. var commands = m.MigrateFromModel(type, _provider);
  279. foreach(var s in commands)
  280. batch.QueueForTransaction(new QueryCommand(s, _provider));
  281. batch.ExecuteTransaction();
  282. migrated.Add(type);
  283. }
  284. }
  285. }
  286. }