1: #region Usings
2:
3: using System;
4: using System.Collections.Generic;
5: using Castle.Facilities.NHibernateIntegration;
6: using AimKai.Core.Interfaces;
7: using AimKai.Core.Resources;
8: using AimKai.Core.Util;
9: using log4net;
10: using NHibernate;
11: using NHibernate.Criterion;
12: using System.Linq;
13:
14: #endregion Usings
15:
16: /// <summary>
17: /// Base nhibernate repository
18: /// </summary>
19: /// <typeparam name="T">Type</typeparam>
20: public abstract class NHibernateBaseRepository<T> : INHibernateBaseRepository<T>
21: {
22: #region Fields
23:
24: /// <summary>
25: /// Session manager
26: /// </summary>
27: protected readonly ISessionManager SessionManager;
28:
29: #endregion Fields
30:
31: #region Properties
32:
33: /// <summary>
34: /// Gets the current session
35: /// </summary>
36: public virtual ISession Session
37: {
38: get { return SessionManager.OpenSession(); }
39: }
40:
41: /// <summary>
42: /// Gets the base log here
43: /// </summary>
44: public ILog NHibernateBaseRepositoryLog = LogManager.GetLogger(typeof (NHibernateBaseRepository<T>));
45:
46: #endregion Properties
47:
48: #region Constructors
49:
50: /// <summary>
51: /// Set session manager via constructor
52: /// </summary>
53: /// <param name="sessionManager"></param>
54: protected NHibernateBaseRepository(ISessionManager sessionManager)
55: {
56: SessionManager = sessionManager;
57: }
58:
59: #endregion Constructors
60:
61: #region Public Methods
62:
63: #region INHibernateBaseRespository<T> Members
64:
65: /// <summary>
66: /// Gets the current session in the repository
67: /// </summary>
68: /// <returns>Current session</returns>
69: public ISession GetCurrentSession()
70: {
71: return Session;
72: }
73:
74: /// <summary>
75: /// Finds an entity by passed identifier
76: /// </summary>
77: /// <param name="id">Identifier</param>
78: /// <returns>Entity matching identifier</returns>
79: public T FindById(long id)
80: {
81: return Session.Get<T>(id);
82: }
83:
84: /// <summary>
85: /// Loads an entity by passed identifier
86: /// </summary>
87: /// <param name="id">Identifier</param>
88: /// <returns>Entity matching identifier</returns>
89: public T Load(long id)
90: {
91: return Session.Load<T>(id);
92: }
93:
94: /// <summary>
95: /// Saves entity
96: /// </summary>
97: /// <param name="t">Entity to save</param>
98: public void Save(T t)
99: {
100: //Use transaction here
101: using (var tx = Session.BeginTransaction())
102: {
103: try
104: {
105: //Check to see if we can validate
106: var validateMethod = t.GetType().GetMethod("Validate");
107: if (validateMethod != null)
108: validateMethod.Invoke(t, null);
109:
110: //Save here
111: Session.Save(t);
112: tx.Commit();
113: }
114: catch (Exception ex)
115: {
116: tx.Rollback();
117:
118: // throw not saved exception
119: NHibernateBaseRepositoryLog.Error(ex);
120: throw new CoreException("NHibernateBaseRepository_NotSaved", ExceptionMessages.NHibernateBaseRepository_NotSaved, ex,
121: new object[] {"Save", ex.Message});
122: }
123: }
124: }
125:
126: /// <summary>
127: /// Saves or updates entity
128: /// </summary>
129: /// <param name="t">Entity to save or update</param>
130: public T SaveOrUpdate(T t)
131: {
132: //Use transaction here
133: using (var tx = Session.BeginTransaction())
134: {
135: try
136: {
137: Session.SaveOrUpdate(t);
138: tx.Commit();
139: }
140: catch (Exception ex)
141: {
142: tx.Rollback();
143:
144: // throw not saved exception
145: NHibernateBaseRepositoryLog.Error(ex);
146: throw new CoreException("NHibernateBaseRepository_NotSaved",
147: ExceptionMessages.NHibernateBaseRepository_NotSaved, ex,
148: new object[] {"Save or Update", ex.Message});
149: }
150: }
151: return t;
152: }
153:
154: /// <summary>
155: /// Deletes entity
156: /// </summary>
157: /// <param name="t">Entity to delete</param>
158: public void Delete(T t)
159: {
160: using (var tx = Session.BeginTransaction())
161: {
162: try
163: {
164: Session.Delete(t);
165: tx.Commit();
166: }
167: catch (Exception ex)
168: {
169: tx.Rollback();
170:
171: // throw not saved exception
172: NHibernateBaseRepositoryLog.Error(ex);
173: throw new CoreException("NHibernateBaseRepository_NotSaved",
174: ExceptionMessages.NHibernateBaseRepository_NotSaved, ex,
175: new object[] { "Delete", ex.Message });
176: }
177: }
178: }
179:
180: /// <summary>
181: /// Finds all entities and passes back as a collection
182: /// </summary>
183: /// <returns>Collection of entities</returns>
184: public IList<T> FindAll()
185: {
186: //Builds a criteria to pull back a collection of all items that match this type
187: return Session.CreateCriteria(typeof(T)).List<T>();
188: }
189:
190: /// <summary>
191: /// Finds all entities by passed order and passes back as a collection
192: /// </summary>
193: /// <param name="orders">Orders</param>
194: /// <returns>Collection of entities</returns>
195: public IList<T> FindAll(params Order[] orders)
196: {
197: return AddOrders(Session.CreateCriteria(typeof(T))).List<T>();
198: }
199:
200: /// <summary>
201: /// Finds all entities and passes back as a collection within the range specified
202: /// </summary>
203: /// <param name="firstResult">First result</param>
204: /// <param name="numberOfResults">Number of results to return</param>
205: /// <returns>Collection of entities</returns>
206: public IList<T> FindAll(int firstResult, int numberOfResults)
207: {
208: return Session.CreateCriteria(typeof(T))
209: .SetFirstResult(firstResult)
210: .SetMaxResults(numberOfResults)
211: .List<T>();
212: }
213:
214: /// <summary>
215: /// Finds all entities and passes back as a collection within the range specified
216: /// </summary>
217: /// <param name="firstResult">First result</param>
218: /// <param name="numberOfResults">Number of results to return</param>
219: /// <param name="orders">Orders</param>
220: /// <returns>Collection of entities</returns>
221: public IList<T> FindAll(int firstResult, int numberOfResults, params Order[] orders)
222: {
223: return AddOrders(Session.CreateCriteria(typeof(T)))
224: .SetMaxResults(numberOfResults)
225: .SetFirstResult(firstResult)
226: .List<T>();
227: }
228:
229: /// <summary>
230: /// Finds all entities and passes back as a collection within the range specified
231: /// </summary>
232: /// <param name="firstResult">First result</param>
233: /// <param name="numberOfResults">Number of results</param>
234: /// <param name="sortFields">Sort order dictionary</param>
235: /// <returns>Collection of entities</returns>
236: public IList<T> FindAll(int firstResult, int numberOfResults, IDictionary<string, bool> sortFields)
237: {
238: var orders = new List<Order>();
239: foreach (var item in sortFields)
240: {
241: var item1 = item;
242: if (typeof(T).GetProperties().Where(x => x.Name == item1.Key).Count() == 0)
243: throw new CoreException("NHibernateBaseRepository_SortParameterNotValid",
244: ExceptionMessages.NHibernateBaseRepository_SortParameterNotValid,
245: new object[] { item1.Key });
246: orders.Add(new Order(item1.Key, item1.Value));
247: }
248: return AddOrders(Session.CreateCriteria(typeof(T)))
249: .SetMaxResults(numberOfResults)
250: .SetFirstResult(firstResult)
251: .List<T>();
252: }
253:
254: /// <summary>
255: /// Finds entities by criteria
256: /// </summary>
257: /// <param name="dc">Detatched criteria</param>
258: /// <returns>Collection of entities that match the passed criteria</returns>
259: public IList<T> FindByCriteria(DetachedCriteria dc)
260: {
261: return dc.GetExecutableCriteria(Session).List<T>();
262: }
263:
264: /// <summary>
265: /// Finds entities by criteria and paging
266: /// </summary>
267: /// <param name="dc">Detatched criteria</param>
268: /// <param name="firstResult">First result</param>
269: /// <param name="numberOfResults">Number of results to return</param>
270: /// <returns>Collection of entities that match the passed criteria</returns>
271: public IList<T> FindByCriteria(DetachedCriteria dc, int firstResult, int numberOfResults)
272: {
273: //Set paging
274: dc.SetFirstResult(firstResult).SetMaxResults(numberOfResults);
275:
276: //Execute criteria
277: return dc.GetExecutableCriteria(Session).List<T>();
278: }
279:
280: /// <summary>
281: /// Finds entities by criteria, paging and ordering
282: /// </summary>
283: /// <param name="dc">Detatched criteria</param>
284: /// <param name="firstResult">First result</param>
285: /// <param name="numberOfResults">Number of results to return</param>
286: /// <param name="orders">Orders</param>
287: /// <returns>Collection of entities that match the passed criteria</returns>
288: public IList<T> FindByCriteria(DetachedCriteria dc, int firstResult, int numberOfResults, params Order[] orders)
289: {
290: return AddOrders(dc, orders).SetFirstResult(firstResult).SetMaxResults(numberOfResults)
291: .GetExecutableCriteria(Session).List<T>();
292: }
293:
294: /// <summary>
295: /// Gets a list of entities by passed query
296: /// </summary>
297: /// <param name="queryString">Query to get entities</param>
298: /// <returns>Collection of entities</returns>
299: public IList<T> FindByQuery(string queryString)
300: {
301: return Session.CreateQuery(queryString).List<T>();
302: }
303:
304: /// <summary>
305: /// Gets a list of entities by passed query and parameters
306: /// </summary>
307: /// <param name="queryString">Query to get entities</param>
308: /// <param name="parameters">Parameters to set in query</param>
309: /// <returns>Collection of entities</returns>
310: public IList<T> FindByQuery(string queryString, params object[] parameters)
311: {
312: var query = Session.CreateQuery(queryString);
313: if (parameters != null)
314: {
315: var count = 0;
316: foreach (var parameter in parameters)
317: {
318: query.SetParameter(count, parameter);
319: count++;
320: }
321: }
322: return query.List<T>();
323: }
324:
325: /// <summary>
326: /// Gets a list of entities by passed query
327: /// </summary>
328: /// <param name="queryString">Query to get entities</param>
329: /// <param name="firstResult">First result</param>
330: /// <param name="numberOfResults">Number of results to return</param>
331: /// <returns>Collection of entities</returns>
332: public IList<T> FindByQuery(string queryString, int firstResult, int numberOfResults)
333: {
334: return Session.CreateQuery(queryString)
335: .SetFirstResult(firstResult)
336: .SetMaxResults(numberOfResults)
337: .List<T>();
338: }
339:
340: /// <summary>
341: /// Gets a list of entities by passed query and parameters
342: /// </summary>
343: /// <param name="queryString">Query to get entities</param>
344: /// <param name="firstResult">First result</param>
345: /// <param name="numberOfResults">Number of results to return</param>
346: /// <param name="parameters">Parameters to set in query</param>
347: /// <returns>Collection of entities</returns>
348: public IList<T> FindByQuery(string queryString, int firstResult, int numberOfResults, params object[] parameters)
349: {
350: var query = Session.CreateQuery(queryString);
351: if (parameters != null)
352: {
353: var count = 0;
354: foreach (var parameter in parameters)
355: {
356: query.SetParameter(count, parameter);
357: count++;
358: }
359: }
360: return query.List<T>();
361: }
362:
363: /// <summary>
364: /// Finds one entity that matches criteria and throws exception otherwise
365: /// </summary>
366: /// <param name="criteria">Criteria</param>
367: /// <returns>Entity matching criteria</returns>
368: public T FindOne(DetachedCriteria criteria)
369: {
370: return criteria.GetExecutableCriteria(Session).UniqueResult<T>();
371: }
372:
373: /// <summary>
374: /// Finds first entity in collection that matches criteria
375: /// </summary>
376: /// <param name="criteria">Criteria</param>
377: /// <returns>First entity</returns>
378: public T FindFirst(DetachedCriteria criteria)
379: {
380: //Do we have any results?
381: var results = criteria.SetMaxResults(1)
382: .GetExecutableCriteria(Session).List<T>();
383:
384: return (results.Count > 0) ? results[0] : default(T);
385: }
386:
387: /// <summary>
388: /// Finds first entity in collection that matches criteria and order params
389: /// <remarks>Can be used to get last in a collection</remarks>
390: /// </summary>
391: /// <param name="criteria">Criteria</param>
392: /// <param name="orders">Orders</param>
393: /// <returns>First entity</returns>
394: public T FindFirst(DetachedCriteria criteria, params Order[] orders)
395: {
396: var results = AddOrders(criteria, orders).SetMaxResults(1)
397: .GetExecutableCriteria(Session).List<T>();
398:
399: return (results.Count > 0) ? results[0] : default(T);
400: }
401:
402: /// <summary>
403: /// Get count of entities that match criteria
404: /// </summary>
405: /// <param name="criteria">Criteria</param>
406: /// <returns>Count of number of entities that match criteria</returns>
407: public long Count(DetachedCriteria criteria)
408: {
409: return Convert.ToInt64(criteria.GetExecutableCriteria(Session)
410: .SetProjection(Projections.RowCountInt64()).UniqueResult());
411: }
412:
413: /// <summary>
414: /// Get count of entities
415: /// </summary>
416: /// <returns>Count of entities</returns>
417: public long Count()
418: {
419: return Convert.ToInt64(Session.CreateCriteria(typeof(T)).SetProjection(Projections.RowCountInt64()).UniqueResult());
420: }
421:
422: /// <summary>
423: /// Determines if at least one entity exists that matches passed criteria
424: /// </summary>
425: /// <param name="criteria">Criteria</param>
426: /// <returns><c>true</c> if exists</returns>
427: public bool Exists(DetachedCriteria criteria)
428: {
429: return Count(criteria) > 0;
430: }
431:
432: #endregion INHibernateBaseRespository<T> Members
433:
434: #endregion Public Methods
435:
436: #region Private Methods
437:
438: /// <summary>
439: /// Adds orders to detached criteria
440: /// </summary>
441: /// <param name="dc">Detached criteria</param>
442: /// <param name="orders">Orders</param>
443: /// <returns>Criteria with orders</returns>
444: private static DetachedCriteria AddOrders(DetachedCriteria dc, params Order[] orders)
445: {
446: //Build orders
447: if (orders != null)
448: foreach (var order in orders)
449: dc.AddOrder(order);
450:
451: return dc;
452: }
453:
454: /// <summary>
455: /// Adds orders to detached criteria
456: /// </summary>
457: /// <param name="dc">criteria</param>
458: /// <param name="orders">Orders</param>
459: /// <returns>Criteria with orders</returns>
460: private static ICriteria AddOrders(ICriteria dc, params Order[] orders)
461: {
462: //Build orders
463: if (orders != null)
464: foreach (var order in orders)
465: dc.AddOrder(order);
466:
467: return dc;
468: }
469:
470: #endregion Private Methods
471: }