使用NHibernate性能问题获取大块数据

时间:2012-07-26 09:49:15

标签: c# sql-server nhibernate

我有一个50k数据块。我使用NHibernate来检索所有(检索所有必要的)。但是由于拥有通过连接5-7个表创建的大型数据集,NHibernate大约需要一分钟。 缓慢提取的主要原因可能是连接表,NHibernate为每个表的每一行创建查询。我理解这是必要的,因为NHibernate需要将每一行映射到一个对象,但必须删除这个开销。

有没有办法在BLOCK中获取数据然后使用NHibernate创建对象。 我包括我的映射文件以及代码 -

的App.config

    <?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
    </configSections>
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

        <bytecode-provider type="lcg"/>
        <reflection-optimizer use="true"/>
        <session-factory>
            <property name="connection.provider" >
                NHibernate.Connection.DriverConnectionProvider
            </property>
            <property name="connection.driver_class">
                NHibernate.Driver.SqlClientDriver
            </property>
            <property name="connection.connection_string">
                Data Source=dewashish-pc\sqlexpress;Initial Catalog=NHibernateTest;Integrated Security=True;
            </property>
            <property name="dialect">
                NHibernate.Dialect.MsSql2005Dialect
            </property>
            <property name="show_sql">
                false
            </property>
            <property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>

        </session-factory>
    </hibernate-configuration>
</configuration>

Branch.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateSample" namespace="NHibernateSample">
<class name="Branch" table="Branch">
  <id name="BranchCode"/>
  <property name="BranchCode"/>
  <property name="BranchName"/>
  <bag name="EmployeeList" cascade="all-delete-orphan" inverse="false"  fetch="join" lazy="false">
      <key column="BranchCode"/>
      <one-to-many class="Employee" />
  </bag>
</class>

</hibernate-mapping>

Employee.hbm.xml

    <?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateSample" namespace="NHibernateSample">
  <class name="Employee" table="Employee">
      <id name="EmployeeId"/>
      <property name="EmployeeId"/>
      <property name="FirstName"/>
      <property name="LastName"/>
      <property name="BranchCode"/>
  </class>
</hibernate-mapping>

Banch.cs

    using System.Collections.Generic; 
using System.Text; 
using System; 


namespace NHibernateSample 
{
    [Serializable]
    public class Branch
    {
        private String branchCode;
        private String branchName;
        private IList<Employee> employeeList = new List<Employee>();

        public virtual IList<Employee> EmployeeList
        {
            get { return employeeList; }
            set { employeeList = value; }
        }
        public virtual String BranchCode
        {
            get { return branchCode; }
            set { branchCode = value; }
        }

        public virtual String BranchName
        {
            get { return branchName; }
            set { branchName = value; }
        }

        public Branch() { }
    }
}

Employee.cs

    using System;
using System.Collections.Generic;
using System.Text;

namespace NHibernateSample
{
    public class Employee
    {
        String employeeId;
        String firstName;
        String lastName;
        String branchCode;

        public virtual String EmployeeId
        {
            get { return employeeId; }
            set { employeeId = value; }
        }

        public virtual String FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }

        public virtual String LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }

        public virtual String BranchCode
        {
            get { return branchCode; }
            set { branchCode = value; }
        }

        public Employee()
        { }
    }
}

Form1.cs的

    using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using NHibernate;
using NHibernate.Cfg;
using System.Reflection;
using System.Collections;

namespace NHibernateSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            ConfigureNHibernate();
            LoadData();
        }

        static ISessionFactory SessionFactory;
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();


        private void LoadData()
        {
            sw.Start();

            using (ISession session = SessionFactory.OpenSession())
            {
                long b = sw.ElapsedMilliseconds;
                try
                {

                    if (session.IsConnected)
                    { 
                        // as br order by br.BranchCode asc
                        IQuery query = session.CreateQuery("from Branch");
                        IList<Branch> iList = query.List<Branch>();
                        dvData.DataSource = iList;
                        int a = 0;
                        foreach (Branch br in iList)
                        {
                            a++;
                        }
                        MessageBox.Show(((sw.ElapsedMilliseconds - b)) + " - MilliSeconds to fetch " + System.Environment.NewLine + a.ToString() + " - Rows");
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);

                }
            }
        }


        private void ConfigureNHibernate()
        {
            try
            {
                Configuration cfg = new Configuration();
                cfg.Configure();

                Assembly allocationAssembly = typeof(Branch).Assembly;
                cfg.AddAssembly(allocationAssembly);

                SessionFactory = cfg.BuildSessionFactory();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

    }
}

我无法发布SQL-Profiler的图像,因为我没有足够的声誉,但会按需提供。 感谢....

1 个答案:

答案 0 :(得分:1)

另一种方法是使用轻量级微ORM(例如Dapper)进行与DB的任何大数据/高频通信。

它会显着提高您的表现。