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

标签 c# sql-server nhibernate

我有一个 50k 数据 block 。我使用 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>

分支.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>

员工.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 的图像,因为我没有足够的声誉,但会根据需要提供。 谢谢....

最佳答案

另一种方法是使用轻量级的微型 ORM,例如 Dapper用于与数据库的任何大数据/高频通信。

它将显着提高您的表现。

关于c# - 使用 NHibernate 性能问题获取大块数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11666692/

相关文章:

c# - 我应该使用构造函数注入(inject)还是 IoC.Resolve?

c# - 如何更有效地使用 SiteMap?

c# - EF映射一对一可选

c# - 在流畅的 NHibernate SubclassMap 中映射多列用户类型的正确方法是什么?

c# - 如何在按回车键后使用 MonoMac 在 NSTextField 中插入回车符?

sql-server - 两个不同列的 SUM 和 DISTINCT

java - 使用PreparedStatements时SQL Server死锁

sql - 使用 SQL CASE 语句动态更改要选择的表

c# - 什么是限制请求数?为什么是 `Timeout while getting a connection from pool` ?

sql - NHibernate QueryOver : Disjuction with restriction in join