远程数据库的响应速度很慢使用NHibernate asp.net应用程序的 [英] Remote Database response very slow of asp.net application using NHIbernate

查看:578
本文介绍了远程数据库的响应速度很慢使用NHibernate asp.net应用程序的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能错过了一些东西来跟踪在波纹管code,但它明显放缓远程数据库服务器的响应时间。同时与数据库从那里部署应用程序在同一台机器试图申请工作正常。此外,使用验证NH-探查所有NHibernate的任务。所有查询都在受控的。唯一的原因是数据库服务器的响应时间。此外,分析了数据库服务器,服务器是很好,但是这是通过远程数据库服务器运行时,它是缓慢的唯一的应用程序。

I may be missed something to track in the bellow code, but it is slowing down remote database server response time. Application is working fine while tried with Database from the same machine where application deployed. Also, verified all the nHibernate tasks using NH-Profiler. All queries are under controlled. The only reason is response time of DB server. Also, analyzed the DB server, server is fine but this is the only application which is slow while running through Remote Database server.

以下是在通用类,用于所有NHibernate的操作:

Following is the Common Class, used for all nHibernate operations :

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
    }

我们在下列方式调用上面的类:

We are calling above class in following manner :

public static bool CheckIfUserNameAlreadyExists(string username)
    {
        bool isExist;
        using (var userRepo = new CommonRepository())
        {
            isExist = userRepo.FindBySpecificColumn<User>("LoginId", username) != null;
        }
        return isExist;
    }

我们正在使用的流利的映射在应用程序中。

We are using Fluent Mapping in the application.

请说明是否有任何需要在公共库类改变或需要实现一些其他的模式。

Please suggest if there are any need to change in the Common repository class or need to implement some other pattern.

在此先感谢!

推荐答案

有些事情要检查:


  • 在您的映射 - 你渴望通过指定不lazyload加载整个用户图形

  • 请检查产生证实上述
  • 的SQL
  • 是否有大量的用户 - 你有到位的指数

  • 如果您使用的是伐木工具,如log4net的 - 确保你没有在调试模式或类似
  • 登录NHibernate的信息
  • In your mappings - are you eager loading the entire user graph by specifying not lazyload
  • Check to see the SQL generated to confirm the above
  • Are there a large amount of users - Do you have an index in place
  • If you are using logging tools like log4net - make sure you are not logging NHibernate info in debug mode or similar

它也好像你是有可能造成在每次请求一个会话工厂(取决于存储库是如何范围),这就是昂贵。你的会话工厂应该是一个独立的,并抛出每个Web请求的会话范围的Web请求的生命周期。

It also seems like you are potentially creating a session factory on every request (depending on how that repository is scoped), which is expensive. Your session factory should be a singleton and dish out a session per web request scoped to lifetime of the web request.

配置应该真正在一次应用程序启动时运行。

The configuration should be really be run once at application startup.

这篇关于远程数据库的响应速度很慢使用NHibernate asp.net应用程序的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆