1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.ActiveRecord
18 using System
.Collections
;
19 using Castle
.ActiveRecord
.Framework
;
21 using NHibernate
.Expression
;
24 /// Base class for all ActiveRecord Generic classes.
25 /// Implements all the functionality to simplify the code on the subclasses.
28 public abstract class ActiveRecordBase
<T
> : ActiveRecordBase
30 #region protected internal static
32 #region Create/Update/Save/Delete/Refresh
37 /// Creates (Saves) a new instance to the database.
39 /// <param name="instance">The ActiveRecord instance to be created on the database</param>
40 protected internal static void Create(T instance
)
42 ActiveRecordBase
.Create(instance
);
50 /// Deletes the instance from the database.
52 /// <param name="instance">The ActiveRecord instance to be deleted</param>
53 protected internal static void Delete(T instance
)
55 ActiveRecordBase
.Delete(instance
);
63 /// Deletes all rows for the specified ActiveRecord type
66 /// This method is usually useful for test cases.
68 public static void DeleteAll()
74 /// Deletes all rows for the specified ActiveRecord type that matches
75 /// the supplied HQL condition
78 /// This method is usually useful for test cases.
80 /// <param name="where">HQL condition to select the rows to be deleted</param>
81 public static void DeleteAll(String where
)
83 DeleteAll(typeof(T
), where
);
87 /// Deletes all <typeparamref name="T"/> objects, based on the primary keys
88 /// supplied on <paramref name="pkValues" />.
90 /// <returns>The number of objects deleted</returns>
91 public static int DeleteAll(IEnumerable pkValues
)
93 return DeleteAll(typeof(T
), pkValues
);
101 /// Refresh the instance from the database.
103 /// <param name="instance">The ActiveRecord instance to be reloaded</param>
104 protected internal static void Refresh(T instance
)
106 ActiveRecordBase
.Refresh(instance
);
114 /// Persists the modification on the instance
115 /// state to the database.
117 /// <param name="instance">The ActiveRecord instance to be updated on the database</param>
118 protected internal static void Update(T instance
)
120 ActiveRecordBase
.Update(instance
);
128 /// Saves the instance to the database. If the primary key is unitialized
129 /// it creates the instance on the database. Otherwise it updates it.
131 /// If the primary key is assigned, then you must invoke <see cref="Create"/>
132 /// or <see cref="Update"/> instead.
135 /// <param name="instance">The ActiveRecord instance to be saved</param>
136 protected internal static void Save(T instance
)
138 ActiveRecordBase
.Save(instance
);
142 /// Saves a copy of the instance to the database. If the primary key is unitialized
143 /// it creates the instance on the database. Otherwise it updates it.
145 /// If the primary key is assigned, then you must invoke <see cref="Create"/>
146 /// or <see cref="Update"/> instead.
149 /// <param name="instance">The transient instance to be saved</param>
150 /// <returns>The saved ActiveRecord instance.</returns>
151 protected internal static T
SaveCopy(T instance
)
153 return (T
) ActiveRecordBase
.SaveCopy(instance
);
163 /// Invokes the specified delegate passing a valid
164 /// NHibernate session. Used for custom NHibernate queries.
166 /// <param name="call">The delegate instance</param>
167 /// <param name="instance">The ActiveRecord instance</param>
168 /// <returns>Whatever is returned by the delegate invocation</returns>
169 protected static object Execute(NHibernateDelegate call
, object instance
)
171 return Execute(typeof(T
), call
, instance
);
175 /// Executes the query and return a strongly typed result
177 /// <param name="query">The query.</param>
178 /// <returns>The query result.</returns>
179 protected internal static R ExecuteQuery2
<R
>(IActiveRecordQuery
<R
> query
)
181 return (R
) ExecuteQuery(query
);
189 /// Returns the number of records of <typeparamref name="T"/> in the database
192 /// <code escaped="true">
194 /// public class User : ActiveRecordBase<User>
198 /// public static int CountAllUsers()
200 /// return Count(); // Equivalent to: Count(typeof(User));
205 /// <returns>The count query result</returns>
206 protected internal static int Count()
208 return Count(typeof(T
));
212 /// Returns the number of records of <typeparamref name="T"/> in the database
215 /// <code escaped="true">
217 /// public class User : ActiveRecordBase<User>
221 /// public static int CountAllUsersLocked()
223 /// return Count("IsLocked = ?", true); // Equivalent to: Count(typeof(User), "IsLocked = ?", true);
228 /// <param name="filter">A sql where string i.e. Person=? and DOB > ?</param>
229 /// <param name="args">Positional parameters for the filter string</param>
230 /// <returns>The count result</returns>
231 protected internal static int Count(String filter
, params object[] args
)
233 return Count(typeof(T
), filter
, args
);
237 /// Check if any instance matching the criteria exists in the database.
239 /// <param name="criteria">The criteria expression</param>
240 /// <returns>The count result</returns>
241 protected internal static int Count(params ICriterion
[] criteria
)
243 return Count(typeof(T
), criteria
);
247 /// Returns the number of records of the specified
248 /// type in the database
250 /// <param name="detachedCriteria">The criteria expression</param>
251 /// <returns>The count result</returns>
252 protected internal static int Count(DetachedCriteria detachedCriteria
)
254 return Count(typeof(T
), detachedCriteria
);
262 /// Check if there is any records in the db for <typeparamref name="T"/>
264 /// <returns><c>true</c> if there's at least one row</returns>
265 public static bool Exists()
267 return ActiveRecordBase
.Exists(typeof(T
));
271 /// Check if there is any records in the db for <typeparamref name="T"/>
273 /// <param name="filter">A sql where string i.e. Person=? and DOB > ?</param>
274 /// <param name="args">Positional parameters for the filter string</param>
275 /// <returns><c>true</c> if there's at least one row</returns>
276 public static bool Exists(String filter
, params object[] args
)
278 return Exists(typeof(T
), filter
, args
);
282 /// Check if the <paramref name="id"/> exists in the database.
284 /// <typeparam name="PkType">The <c>System.Type</c> of the PrimaryKey</typeparam>
285 /// <param name="id">The id to check on</param>
286 /// <returns><c>true</c> if the ID exists; otherwise <c>false</c>.</returns>
287 public static bool Exists
<PkType
>(PkType id
)
289 return Exists(typeof(T
), id
);
293 /// Check if any instance matching the criteria exists in the database.
295 /// <param name="criteria">The criteria expression</param>
296 /// <returns><c>true</c> if an instance is found; otherwise <c>false</c>.</returns>
297 public static bool Exists(params ICriterion
[] criteria
)
299 return Exists(typeof(T
), criteria
);
303 /// Check if any instance matching the criteria exists in the database.
305 /// <param name="detachedCriteria">The criteria expression</param>
306 /// <returns><c>true</c> if an instance is found; otherwise <c>false</c>.</returns>
307 public static bool Exists(DetachedCriteria detachedCriteria
)
309 return Exists(typeof(T
), detachedCriteria
);
317 /// Returns all the instances that match the detached criteria.
319 /// <param name="criteria">Detached criteria</param>
320 /// <param name="orders">Optional ordering</param>
321 /// <returns>All entities that match the criteria</returns>
322 public static T
[] FindAll(DetachedCriteria criteria
, params Order
[] orders
)
324 return (T
[]) FindAll(typeof(T
), criteria
, orders
);
328 /// Returns all instances found for <typeparamref name="T"/>
330 /// <returns>An <see cref="Array"/> of <typeparamref name="T"/></returns>
331 public static T
[] FindAll()
333 return (T
[]) FindAll(typeof(T
));
337 /// Returns all instances found for the specified type
338 /// using sort orders and criteria.
340 /// <param name="order">An <see cref="Order"/> object.</param>
341 /// <param name="criteria">The criteria expression</param>
342 /// <returns>The <see cref="Array"/> of results.</returns>
343 public static T
[] FindAll(Order order
, params ICriterion
[] criteria
)
345 return (T
[]) FindAll(typeof(T
), new Order
[] {order}
, criteria
);
349 /// Returns all instances found for <typeparamref name="T"/>
350 /// using sort orders and criteria.
352 /// <param name="orders"></param>
353 /// <param name="criteria"></param>
354 /// <returns>An <see cref="Array"/> of <typeparamref name="T"/></returns>
355 public static T
[] FindAll(Order
[] orders
, params ICriterion
[] criteria
)
357 return (T
[]) FindAll(typeof(T
), orders
, criteria
);
361 /// Returns all instances found for <typeparamref name="T"/>
364 /// <param name="criteria"></param>
365 /// <returns>An <see cref="Array"/> of <typeparamref name="T"/></returns>
366 public static T
[] FindAll(params ICriterion
[] criteria
)
368 return (T
[]) FindAll(typeof(T
), criteria
);
373 #region FindAllByProperty
376 /// Finds records based on a property value
378 /// <param name="property">A property name (not a column name)</param>
379 /// <param name="value">The value to be equals to</param>
380 /// <returns>An <see cref="Array"/> of <typeparamref name="T"/></returns>
381 public static T
[] FindAllByProperty(String property
, object value)
383 return (T
[]) FindAllByProperty(typeof(T
), property
, value);
387 /// Finds records based on a property value
389 /// <param name="orderByColumn">The column name to be ordered ASC</param>
390 /// <param name="property">A property name (not a column name)</param>
391 /// <param name="value">The value to be equals to</param>
392 /// <returns>An <see cref="Array"/> of <typeparamref name="T"/></returns>
393 public static T
[] FindAllByProperty(String orderByColumn
, String property
, object value)
395 return (T
[]) FindAllByProperty(typeof(T
), orderByColumn
, property
, value);
400 #region FindByPrimaryKey/Find/TryFind
403 /// Finds an object instance by an unique ID
405 /// <param name="id">ID value</param>
406 /// <exception cref="ObjectNotFoundException">if the row is not found</exception>
407 /// <returns>T</returns>
408 public static T
Find(object id
)
410 return (T
) FindByPrimaryKey(typeof(T
), id
, true);
414 /// Finds an object instance by an unique ID.
415 /// If the row is not found this method will not throw an exception.
417 /// <param name="id">ID value</param>
418 /// <returns>A <typeparamref name="T"/></returns>
419 public static T
TryFind(object id
)
421 return (T
) FindByPrimaryKey(typeof(T
), id
, false);
425 /// Finds an object instance by an unique ID for <typeparamref name="T"/>
427 /// <param name="id">ID value</param>
428 /// <returns>A <typeparamref name="T"/></returns>
429 protected internal static T
FindByPrimaryKey(object id
)
431 return (T
) FindByPrimaryKey(typeof(T
), id
);
435 /// Finds an object instance by a unique ID for <typeparamref name="T"/>
437 /// <param name="id">ID value</param>
438 /// <param name="throwOnNotFound"><c>true</c> if you want to catch an exception
439 /// if the object is not found</param>
440 /// <returns>A <typeparamref name="T"/></returns>
441 /// <exception cref="ObjectNotFoundException">if <c>throwOnNotFound</c> is set to
442 /// <c>true</c> and the row is not found</exception>
443 protected internal static T
FindByPrimaryKey(object id
, bool throwOnNotFound
)
445 return (T
) FindByPrimaryKey(typeof(T
), id
, throwOnNotFound
);
453 /// Searches and returns the first row for <typeparamref name="T"/>.
455 /// <param name="criteria">Detached criteria.</param>
456 /// <param name="orders">The sort order - used to determine which record is the first one.</param>
457 /// <returns>A <c>targetType</c> instance or <c>null</c>.</returns>
458 public static T
FindFirst(DetachedCriteria criteria
, params Order
[] orders
)
460 return (T
) FindFirst(typeof(T
), criteria
, orders
);
464 /// Searches and returns the first row for <typeparamref name="T"/>
466 /// <param name="order">The sort order - used to determine which record is the first one</param>
467 /// <param name="criteria">The criteria expression</param>
468 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
469 public static T
FindFirst(Order order
, params ICriterion
[] criteria
)
471 return (T
) FindFirst(typeof(T
), new Order
[] {order}
, criteria
);
475 /// Searches and returns the first row for <typeparamref name="T"/>
477 /// <param name="orders">The sort order - used to determine which record is the first one</param>
478 /// <param name="criteria">The criteria expression</param>
479 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
480 public static T
FindFirst(Order
[] orders
, params ICriterion
[] criteria
)
482 return (T
) FindFirst(typeof(T
), orders
, criteria
);
486 /// Searches and returns the first row for <typeparamref name="T"/>
488 /// <param name="criteria">The criteria expression</param>
489 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
490 public static T
FindFirst(params ICriterion
[] criteria
)
492 return (T
) FindFirst(typeof(T
), criteria
);
500 /// Searches and returns a row. If more than one is found,
501 /// throws <see cref="ActiveRecordException"/>
503 /// <param name="criteria">The criteria expression</param>
504 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
505 public static T
FindOne(params ICriterion
[] criteria
)
507 return (T
) FindOne(typeof(T
), criteria
);
511 /// Searches and returns a row. If more than one is found,
512 /// throws <see cref="ActiveRecordException"/>
514 /// <param name="criteria">The criteria</param>
515 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
516 public static T
FindOne(DetachedCriteria criteria
)
518 return (T
) FindOne(typeof(T
), criteria
);
523 #region SlicedFindAll
526 /// Returns a portion of the query results (sliced)
528 /// <param name="firstResult">The number of the first row to retrieve.</param>
529 /// <param name="maxResults">The maximum number of results retrieved.</param>
530 /// <param name="orders">An <see cref="Array"/> of <see cref="Order"/> objects.</param>
531 /// <param name="criteria">The criteria expression</param>
532 /// <returns>The sliced query results.</returns>
533 public static T
[] SlicedFindAll(int firstResult
, int maxResults
, Order
[] orders
,
534 params ICriterion
[] criteria
)
536 return (T
[]) SlicedFindAll(typeof(T
), firstResult
, maxResults
, orders
, criteria
);
540 /// Returns a portion of the query results (sliced)
542 /// <param name="firstResult">The number of the first row to retrieve.</param>
543 /// <param name="maxResults">The maximum number of results retrieved.</param>
544 /// <param name="criteria">The criteria expression</param>
545 /// <returns>The sliced query results.</returns>
546 public static T
[] SlicedFindAll(int firstResult
, int maxResults
,
547 params ICriterion
[] criteria
)
549 return (T
[]) SlicedFindAll(typeof(T
), firstResult
, maxResults
, criteria
);
553 /// Returns a portion of the query results (sliced)
555 /// <param name="firstResult">The number of the first row to retrieve.</param>
556 /// <param name="maxResults">The maximum number of results retrieved.</param>
557 /// <param name="orders">An <see cref="Array"/> of <see cref="Order"/> objects.</param>
558 /// <param name="criteria">The criteria expression</param>
559 /// <returns>The sliced query results.</returns>
560 public static T
[] SlicedFindAll(int firstResult
, int maxResults
, DetachedCriteria criteria
, params Order
[] orders
)
562 return (T
[]) SlicedFindAll(typeof(T
), firstResult
, maxResults
, orders
, criteria
);