我可能錯過了在波紋管代碼中跟蹤的內容,但它會減慢遠程數據庫服務器的響應時間。當應用程序部署在同一臺機器上的數據庫中嘗試時,應用程序工作正常。另外,使用NH-Profiler驗證所有nHibernate任務。所有查詢都受到控制。唯一的原因是數據庫服務器的響應時間。此外,分析數據庫服務器,服務器是好的,但這是通過遠程數據庫服務器運行速度慢的唯一應用程序。遠程數據庫響應使用NHIbernate的asp.net應用程序的速度非常慢
以下是的通用類,用於所有NHibernate的操作:我們使用流利的映射在
public static bool CheckIfUserNameAlreadyExists(string username)
{
bool isExist;
using (var userRepo = new CommonRepository())
{
isExist = userRepo.FindBySpecificColumn<User>("LoginId", username) != null;
}
return isExist;
}
:
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
}
我們以下面的方式調用上面的類應用。
請提出是否需要更改Common repository類或需要實現其他某種模式。
在此先感謝!
「用戶」表中有多少行? 「用戶」是否與其他實體建立關係?這些關係的「獲取模式」如何?您可以在「日誌」中看到多少SQL命令?這些SQL命令如何?... – Hailton 2012-07-18 06:19:43
@ Hailton - 在NHProfiler中有大約12個SQL命令並且沒有警告。用戶表有超過15000條記錄。所有相關的實體都是lazy loading = false – 2012-07-18 09:40:51
@Rick我認爲通過回答Hailton你指出了你的問題:'所有相關的實體都是lazy loading = false'。這是不好的做法。你應該使用延遲加載。你的方法FindBySpecificColumn返回完整的用戶實體和所有相關的實體。 – 2012-07-19 06:04:16