ERP/MIS开发 Mindscape NHibernate + MySQL 快速开发入门

ORM设计工具:Mindscape NHibernate Designer,请安装Mindscape.NHibernateModelDesigner.vsix文件。

它是一个Visual Studio 2010的插件,运行时效果所示

image

支持Model frist和Database first两种开发模式,如下图所示

image
Update Model from Database,从数据库schema更新模型定义

Update Database from Model 则是以实体定义更新数据库。

设计器会生成一个组件layout文件,用于设计器工作,一个cs文件,对应于实体属性与数据库字段映射,Agent内容如下

public partial class Agent
  {
    public virtual string Name { get; set; }
    public virtual string Position { get; set; }
    public virtual string Description { get; set; }

    static partial void CustomizeMappingDocument(System.Xml.Linq.XDocument mappingDocument);

    internal static System.Xml.Linq.XDocument MappingXml
    {
      get
      {
        var mappingDocument = System.Xml.Linq.XDocument.Parse(@"<?xml version='1.0' encoding='utf-8' ?>
<hibernate-mapping xmlns='urn:nhibernate-mapping-2.2'
                   assembly='" + typeof(Agent).Assembly.GetName().Name + @"'
                   namespace='BusinessLogic'
                   >
  <class name='Agent'
         table='`Agent`'
         >
    <id name='Name'
        column='`Name`'
        >
      <generator class='identity'>
      </generator>
    </id>
    <property name='Position'
              column='`Position`'
              />
    <property name='Description'
              column='`Description`'
              />
  </class>
</hibernate-mapping>");
        CustomizeMappingDocument(mappingDocument);
        return mappingDocument;
      }
    }
  }

MappingXml的值,就是我们开发NHibernate时需要配置的映射文件,由设计器维护。

数据库选用MySQL 5.1。

MySQL 数据表的创建

image

SQL脚本如下
DROP TABLE IF EXISTS `ctu`.`agent`;
CREATE TABLE  `ctu`.`agent` (
  `Name` varchar(40) NOT NULL,
  `Position` varchar(45) NOT NULL,
  `Description` varchar(45) NOT NULL,
  PRIMARY KEY  (`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

先查看一下这个表的数据项,有三笔数据,分别以Jack,Tony,Charles为主键
image

启动Visual Studio 2010,打开Server Explorer,创建一个新的MySQL连接

image

记住这里要勾选Allow saving password,否则当把表拖动到设计器中时,会出现无法连接的异常
把表CTU拖动到NHibernate设计器中,以完成模型的创建

image

在设计器中右键,调出Get Started菜单项

image

如图所示,已经写好了配置文件的主要内容,添加App.config或Web.config文件,把配置内容拷贝到文件中

<configSections>
   <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
   <session-factory>
     <property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
     <property name="connection.connection_string">User Id=root;Password=123;Host=JAMESLI;Database=ctu;Persist Security Info=True;</property>
     <property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
   </session-factory>
</hibernate-configuration>

在项目的启动目录中,添加这2个程序集:NHibernate.ByteCode.Castle.dll和Castle.Core.dll
把Get Started中的NHibernateHelper文件拷贝到项目中

public static class NHibernateHelper
    {
        private static ISessionFactory _sessionFactory;

        internal static ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    var configuration = ConfigurationHelper.CreateConfiguration();
                    _sessionFactory = configuration.BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

        internal static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }
    }
设计如下的测试代码
[TestMethod]
public void TestFetch()
{          
        using (ISession session = NHibernateHelper.OpenSession())
        using (ITransaction tx = session.BeginTransaction())
       {
             string name = "Tony";
             Agent tony = session.Get<Agent>(name);
             string fullName = tony.Description;
        }         
}

启动调试器,进入方法中,效果如下图所示

image

这表明,NHibernate已经成功的从MySQL数据库中取得了数据记录。

从.NET 1.1起,NHibernate就是极力推荐的ORM开发工具。因为没有称心的ORM设计工具,维护数据库字段与实体属性之间的映射关系非常麻烦,而且容易出错。商业的ORM工具,卖点之一就是简化映射文件的设计。不管是用xml文件或是cs文件来维护映射,只要维护关系映射简单,就是很大的进步,如果能熟练操作文章中提到的数据库与实体映射的内容,用NHibernate来开发ERP/MIS应该是很简单轻巧的事情。

写完了这篇文档,检查NHibernate文档,发生有个NHibernate.Tool.hbm2net的软件,解释如下

NHibernate.Tool.hbm2net 是 NHibernate 的附加软件.它使得从hbm.xml映射文件产生源代码成为可能。

在 NHibernate.Tasks目录,有一个叫做Hbm2NetTask的工具,你可以用它自动编译程序(使用NAnt)。


温故而知新,NHibernate拥有很多实用工具,再推荐一个工具NHibernate Profiler工具
在应用程序中添加对HibernatingRhinos.NHibernate.Profiler.Appender.dll程序集的引用,并在启动时添加代码
[TestInitialize]
public void InitializeProfiler()
{
    HibernatingRhinos.NHibernate.Profiler.Appender.NHibernateProfiler.Initialize();

HibernatingRhinos.NHibernate.Profiler.Appender.NHibernateProfiler.Initialize();
以插入跟踪程序,再启动之前的测试方法,切换到NHibernate Profiler的界面中即可看到被发送到服务器的SQL语句。

当然,也可以用SQL Server Profiler来追踪出问题的SQL语句,举例说明
SalesOrderEntity  salesOrder=session.Get<SalesOrderEntity>(5023);
这是用主键来查找数据记录,通常不会有问题。反过来,写两个SQL来对比一下,请看以下两条SQL
SELECT * FROM SalesOrder WHERE CustomerId is NULL
SELECT * FROM SalesOrder WHERE CustomerId =’’
这两句,从SQL的层面来理解,前一句是找出客户编号为空的采购单,后一句是找出客户编号为空白的采购单
对应于CustomerId,一般会用string类型来映射。如果有语句将CustomerId 初试化为string.Empty,而另一段代码
却没有初试化CustomerId,意味着CustomerId为null,这两个ORM语句发送到服务器中去,就会是两种不同的WHERE条件,即CustomerId =’’和CustomerId is NULL,也就是发送的ORM语句与实际SQL查询的结果不一致。
ORM开发中,出现ORM语句的语意与我们设想的SQL不同时,可使用NHibernate Profiler或SQL Server Profiler来追踪有问题的SQL语句,从而修改ORM的写法来排除错误。

posted @ 2011-08-22 18:00  信息化建设  阅读(2867)  评论(2编辑  收藏  举报