我可能会错过以下代码中要跟踪的内容,但这会减慢远程数据库服务器的响应时间。在部署应用程序的同一台机器上尝试使用数据库时,应用程序运行良好。此外,使用 NH-Profiler 验证了所有 nHibernate 任务。所有查询都受到控制。唯一的原因是数据库服务器的响应时间。此外,分析了数据库服务器,服务器很好,但这是唯一一个在通过远程数据库服务器运行时速度很慢的应用程序。
以下是通用类,用于所有 nHibernate 操作:
public class CommonRepository : IDisposable
{
protected static Configuration Config;
protected static ISessionFactory SessionFactory;
protected static ITransaction Transaction;
static readonly object Factorylock = new object();
/// <summary>
/// Configure your repositories. It uses default DB string
/// Create singleton thread safe : found good stuff on Stackoverflow
/// Referrence : http://stackoverflow.com/questions/2362195/ensure-nhibernate-sessionfactory-is-only-created-once
/// </summary>
public CommonRepository()
{
lock (Factorylock)
{
if (SessionFactory == null)
{
// SessionFactory = NonFluentConfiguration();
SessionFactory = FluentConfig(msdnh.util.Config.ConnectionString); //Grab default string from Database
}
}
Session = SessionFactory.OpenSession();
Transaction = Session.BeginTransaction();
}
/// <summary>
/// Configure your repositories
/// </summary>
/// <param name="connectionString">Connection string</param>
public CommonRepository(string connectionString)
{
if (SessionFactory == null)
{
SessionFactory = FluentConfig(connectionString);
}
Session = SessionFactory.OpenSession();
Transaction = Session.BeginTransaction();
}
private static ISessionFactory NonFluentConfiguration()
{
Config = new Configuration();
Config.Configure();
Config.AddAssembly(typeof(CommonRepository).Assembly);
return Config.BuildSessionFactory();
}
private static ISessionFactory FluentConfig(string connString)
{
IPersistenceConfigurer persistenceConfigurer =
MsSqlConfiguration
.MsSql2008
.ConnectionString(connString)
.ShowSql();
// initialize nhibernate with persistance configurer properties
Configuration cfg = persistenceConfigurer
.ConfigureProperties(new Configuration());
// add mappings definition to nhibernate configuration
var persistenceModel = new PersistenceModel();
persistenceModel.AddMappingsFromAssembly(Assembly.Load("Girlpower"));
persistenceModel.Configure(cfg);
// set session factory field which is to be used in tests
return cfg.BuildSessionFactory();
}
protected static ISession Session { get; private set; }
public bool Commit()
{
if (Transaction.IsActive)
{
try { Transaction.Commit(); return true; }
catch (Exception exception)
{
//Error log
return false;
}
}
return false;
}
public bool Rollback()
{
if (Transaction.IsActive)
{
try { Transaction.Rollback(); return true; }
catch (Exception exception)
{
//Error log
return false;
}
}
return false;
}
public void GenerateSchema()
{
new SchemaExport(Config).Execute(true, false, false);
}
private void BuildSchema(Configuration cfg)
{
new SchemaExport(cfg)
.Create(false, true);
}
#region Repository Functions
/// <summary>
/// Saves or updates the object to the database, depending on the value of its identifier property.
/// </summary>
/// <param name="value">
/// A transient instance containing a new or updated state.</param>
public void Save(object value)
{
Session.Save(value);
}
/// <summary>
/// Save object to repository
/// </summary>
/// <param name="value">
/// Object for save</param>
public void SaveorUpdate(object value)
{
Session.SaveOrUpdate(value);
}
/// <summary>
/// Merge / copy state of given object to persit object
/// </summary>
/// <param name="value">Entity</param>
public void SaveorUpdateCopy(object value)
{
Session.Merge(value);
}
/// <summary>
/// Removes a persistent instance from the database.
/// </summary>
/// <param name="value">
/// The instance to be removed.</param>
public void Delete(object value)
{
Session.Delete(value);
}
/// <summary>
/// Delete records from specific entity
/// </summary>
/// <typeparam name="T">Entity name</typeparam>
/// <param name="id">value of record id</param>
public void Delete<T>(int id) where T : class
{
Session.Delete(string.Format("from {0} where id = {1}", typeof(T), id));
}
/// <summary>
/// Update specific fields of entity using IQuery
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="updateColName"></param>
/// <param name="updateColValue"></param>
public void Update<T>(int id, string updateColName, object updateColValue) where T : class
{
var query = CreateQuery<T>(id, updateColName, updateColValue);
query.ExecuteUpdate();
}
private static IQuery CreateQuery<T>(int id, string updateColName, object updateColValue) where T : class
{
return Session.CreateQuery(string.Format("Update {0} set {1} = {2} where id = {3} ", typeof(T), updateColName, updateColValue, id));
}
/// <summary>
/// Delete records from specific entity by speciying column name
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="colName"></param>
public void Delete<T>(int id, string colName) where T : class
{
Session.Delete(string.Format("from {0} where {1} = {2}", typeof(T), colName, id));
}
/// <summary>
/// Returns a strong typed persistent instance of the given named entity with the given identifier, or null if there is no such persistent instance.
/// </summary>
/// <typeparam name="T">The type of the given persistant instance.</typeparam>
/// <param name="id">An identifier.</param>
public T Get<T>(object id)
{
T returnVal = Session.Get<T>(id);
return returnVal;
}
/// <summary>
/// Find Results by Name
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <returns></returns>
public T FindByName<T>(string name)
where T : class
{
var criteria = Session.CreateCriteria<T>();
var targetEntity = typeof(T);
if (targetEntity == typeof(Article))
criteria.Add(Restrictions.Eq("Title", name));
else if (targetEntity == typeof(Category))
criteria.Add(Restrictions.Eq("CatName", name));
else if (targetEntity == typeof(News))
criteria.Add(Restrictions.Eq("Title", name));
else if (targetEntity == typeof(Video))
criteria.Add(Restrictions.Eq("Title", name));
else if (targetEntity == typeof(NewsCategory))
criteria.Add(Restrictions.Eq("NewsCatName", name));
else if (targetEntity == typeof(VideoCategory))
criteria.Add(Restrictions.Eq("VideoCatName", name));
else
criteria.Add(Restrictions.Eq("Name", name));
return FindUnique<T>(criteria);
}
public T FindBySpecificColumn<T>(string colname, string findValue)
where T : class
{
var criteria = Session.CreateCriteria<T>();
criteria.Add(Restrictions.Eq(colname, findValue));
return FindUnique<T>(criteria);
}
public T FindBySpecificColumn<T>(string colname, int findValue)
where T : class
{
var criteria = Session.CreateCriteria<T>();
criteria.Add(Restrictions.Eq(colname, findValue));
return FindUnique<T>(criteria);
}
public IList<T> FindRandomBySpecificColumn<T>(string colname, int findValue)
where T : class
{
var criteria = Session.CreateCriteria<T>();
criteria.Add(Restrictions.Eq(colname, Convert.ToBoolean(findValue)));
criteria.AddOrder(new RandomOrder());
return Find<T>(criteria);
}
public IList<T> FindTopRecents<T>(int recCount, string colName) where T : class
{
return Session.CreateQuery(string.Format("from {0} order by {1} DESC", typeof(T), colName))
.SetFirstResult(0)
.SetMaxResults(recCount)
.List<T>();
}
/// <summary>
/// Returns a list of all instances of type T from the database.
/// </summary>
/// <typeparam name="T">The type of the given persistant instance.</typeparam>
public IList<T> GetAll<T>()
where T : class
{
IList<T> returnVal = Session.CreateCriteria<T>().List<T>();
return returnVal;
}
/// <summary>
/// Returns a list of all instances of type T from the database for pagination
/// </summary>
/// <typeparam name="T">The type of the given persistant instance.</typeparam>
/// <param name="pageIndex">Number- page index.</param>
/// <param name="pageSize">Number - maximum page size.</param>
/// <returns>List of type the given persistent instance</returns>
public IList<T> GetAll<T>(int pageIndex, int pageSize)
where T : class
{
var criteria = Session.CreateCriteria(typeof(T));
if (pageSize > 0)
{
criteria.SetMaxResults(pageSize);
}
return criteria.List<T>();
}
/// <summary>
/// Find Unique values
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="criteria"></param>
/// <returns></returns>
public T FindUnique<T>(ICriteria criteria)
where T : class
{
return (T)criteria.UniqueResult();
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="criteria"></param>
/// <returns></returns>
public IList<T> Find<T>(ICriteria criteria) where T : class
{
return criteria.List<T>();
}
public IList<T> Find<T>(IEnumerable<string> strs)
where T : class
{
IList<ICriterion> objs = strs.Select(Expression.Sql).Cast<ICriterion>().ToList();
var criteria = Session.CreateCriteria(typeof(T));
foreach (var rest in objs)
criteria.SetFirstResult(0);
return criteria.List<T>();
}
public IList<T> Find<T>(ICriteria criteria, PagingInfo paging) where T : class
{
paging.RowCount = Count(criteria);
if (paging.PageSize > 0)
{
criteria.SetMaxResults((int)paging.PageSize);
criteria.SetFirstResult((int)(paging.PageSize * paging.CurrentPage));
}
return criteria.List<T>();
}
protected int Count(ICriteria criteria)
{
//TODO check performance of this method (probably is better to use HQL with the COUNT(*) command)
return criteria.List().Count;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query"></param>
/// <returns></returns>
public IList<T> GetListByQuery<T>(IQuery query)
where T : class
{
var list = query.List<T>();
return list;
}
public ICriteria CreateCriteria<T>() where T : class
{
return Session.CreateCriteria(typeof(T));
}
#endregion
#region IDisposable methods
public void Dispose()
{
if (Session != null)
{
if (Session.IsOpen) Session.Close();
}
}
#endregion
}
我们以下列方式调用上面的类:
public static bool CheckIfUserNameAlreadyExists(string username)
{
bool isExist;
using (var userRepo = new CommonRepository())
{
isExist = userRepo.FindBySpecificColumn<User>("LoginId", username) != null;
}
return isExist;
}
我们在应用程序中使用Fluent Mapping。
请建议是否需要更改公共存储库类或需要实现一些其他模式。
提前致谢!