C#程序通过ORM框架连接Oracle数据库--NHibernate篇

因项目后台库管系统的需要,采用C#做开发语言,Oracle做数据库,ORM框架选择了NHibernate,这个ORM不是我熟悉的EF框架(EntityFramework),但原本心想ORM都差不多的,结果实际操作起来还是有很多坑,加上此前没用过的Oracle数据库,网上相关资料不是很老就是所答非所问。索性现在弄出来了,就做个总结以备不时之需。同时也给像我一样刚接触的朋友一个参考。


 先说下项目配置:

①数据库用的是Oracle11g,部署在公司局域网环境中,通过VPN访问,本机通过 DataGrip 2020.2×64(JB全家桶的一员)做客户端连接。数据库表很简单是模拟用户登录的实验用表:有三个字段LOGID,PWD,USERNAME,具体如下

create table LOGIN
(
    LOGID    NUMBER not null
        constraint LOGIN_PK
            primary key,
    PWD      NUMBER,
    USERNAME VARCHAR2(10)
)

②VS用的是VS2017社区版


1.安装NHibernate(用vs的NuGet安装)

右键项目“引用”选择“管理NuGet”程序包

在“浏览”处搜索Nhibernate,之后下载安装。 

安装完毕后引用会多这几个:

扫描二维码关注公众号,回复: 12428380 查看本文章

对应的packages.json是这样的

2.创建实体对象 

 新建Domain文件夹后创建类GroupInfo.cs为例子,实体对象内属性和数据库表字段一致就可以

注意:NHibernate默认配置为对所有实体使用延迟加载,所以对所有属性(方法)要加Virtual,这个virtual并不是虚方法的意思,EF中也是这样的

namespace NhibernateDemo.Domain
{
    public class GroupInfo
    {
        //NHibernate默认配置为对所有实体使用延迟加载,所以对所有属性(方法)要加Virtual,这个virtual并不是虚方法的意思
        public virtual int LOGID { get; set; }
        public virtual int PWD { get; set; }
        public virtual string USERNAME { get; set; }
    }
}

 3.创建对象映射关系

新建Mapping文件夹LOGIN.hbm.xml文件

注意:通常数据库有多少个表建立所少个xml文件,命名就用数据库表名即可,但是hbm不能省略,因为这是NHibernate用来自动将文件识别为映射文件的标志

注意:在这个文件的属性中“生成操作”一定要选择为“嵌入的资源” 

 LOGIN.hbm.xml文件内容如下:

说明:

①assembly程序集就是你当前存放实体类的程序集,namespace命名空间就是存放实体类的命名空间。

②mapping info中id代表主键,property代表其他字段

③mapping info中name是必填的,就是实体类属性的名称,之后都是选填。

④NHibernate允许我们定义很多合理的默认值。因此,如果不为属性提供明确的列名column,它将根据该属性名为列命名。或者NHibernate可以从类定义中自动推断表的名称或列的类型,这样xml映射文件就会比较简洁。

详细的属性如何填写可以参考链接:

https://nhibernate.info/doc/nhibernate-reference/mapping.html

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
                   assembly="NhibernateDemo" 
                   namespace="NhibernateDemo.Domain">
 
  <!-- more mapping info here -->
  <class name="GroupInfo" table="LOGIN">
    <!--主键-->
    <id name="LOGID" column="LOGID">
      <!--<generator class="int"></generator>-->     
    </id>
    <property name="PWD" column="PWD"/>
    <property name="USERNAME" column="USERNAME"/>
  </class>
  
</hibernate-mapping>

4.配置NHibernate (告诉NHibernate要连接那个数据库)

添加新的xml文件hibernate.cfg.xml

注意:hibernate.cfg.xml文件名字不能更改,否则会找不到

具体如何配置,这个是有模板的(位置在项目根目录packages文件夹中,参考下图),将模板内容粘贴到新创建的hibernate.cfg.xml文件中

这里因为用的是oracle,所以我参考oracle的。 

这里连接的oracle数据库,有几个地方要说明:

①连接字符串(红色标识处需要更改):

  User Id=sde;Password=sde;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.10.199)(PORT=1521))(CONNECT_DATA = (SERVICE_NAME = orcl)))

②方言:一般不用动(10g、11g都是通用的)

  <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>

③SQL查询:在输出面板就能看到自动生成的SQL语句

 <property name="show_sql">true</property>

④oracle连接使用的是Oracle.ManagedDataAccess.dll,因此driver选择OracleManagedDataClientDriver,一定要引用Oracle.ManagedDataAccess.dll

Oracle.ManagedDataAccess.dll地址:

链接:https://pan.baidu.com/s/13wUM6U-Xr7wUcHfwRtes8g 
提取码:qbo4

<?xml version="1.0" encoding="utf-8"?>
<!-- 
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it 
for your own use before compile tests in VisualStudio.
-->
<!-- This is the System.Data.OracleClient.dll provider for Oracle from MS -->
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory name="NHibernate.Test">
    <property name="connection.driver_class">NHibernate.Driver.OracleManagedDataClientDriver</property>
    <property name="connection.connection_string">
      User Id=sde;Password=sde;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.10.199)(PORT=1521))(CONNECT_DATA = (SERVICE_NAME = orcl)))
    </property>
    
    <property name="show_sql">false</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <!-- If your database setup use an ASCII charset, switch following property to true. -->
    <property name="oracle.use_n_prefixed_types_for_unicode">false</property>
    <!-- Depending on your database setup, the default cast length of 4000 may be too big.
		     By example, if previous setting is true, NHibernate may try to use nvarchar2(4000),
		     which will be rejected if its underlying charset is UTF16 and the database
		     MAX_STRING_SIZE is not extended. In such case, reduce it to 2000. -->
    <property name="query.default_cast_length"></property>
    <!--展示SQL语句-->
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>

 !!!!!!最后要将这个文件设置为始终复制到输出目录(这个最关键,否则会失败)

 5.配置NHibernate (告诉NHibernate要连接那个数据库)

 像ADO.NET一样创建一个通用Helper类

类的内容如下:

这里有几点需要说明:

HhibernateHelper.cs文件主要创建一个上下文对象session,相当于EF框架中继承了DBContext的EFDBEntities对象,通过这个上下文对象来操作实体类生成SQL,进而通过底层ADO.NET持久化到数据库中。

using NHibernate;
using NHibernate.Cfg;
using NhibernateDemo.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace NhibernateDemo
{
    //这个类只在客户端第一次需要新会话时创建会话工厂
    public class NhibernateHelper
    {
        private static ISessionFactory _sessionFactory;

        private static ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    var configuration = new Configuration();
                    configuration.Configure();
                    configuration.AddAssembly(typeof(GroupInfo).Assembly);
                    //我们创建一个会话工厂。这是一个昂贵的过程,因此应该只执行一次。
                    //这就是为什么我将其放入此方法的原因,该方法在测试周期内仅执行一次
                    _sessionFactory = configuration.BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

        public static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }
    }
}

6.在你的程序界面封装对象完成添加 

代码如下:

注意:

var tx = session.BeginTransaction(),结尾 处要提交tx.Commit();因为他是基于事务方式提交数据库的,如果不commit,Oracle也无法添加。

  //注册
        private void btnRegistor_Click(object sender, EventArgs e)
        {
            using (var session =NhibernateHelper.OpenSession())
            {
                //开启事务(执行完资源要释放)
                using (var tx = session.BeginTransaction()){
                    //对象封装
                    GroupInfo objGroupInfo = new GroupInfo()
                    {
                        LOGID = Convert.ToInt32(txtLoginId.Text.Trim()),
                        PWD = Convert.ToInt32(txtPwd.Text),
                        USERNAME = txtName.Text.Trim()
                    };
                    session.Save(objGroupInfo);
                    //事务的方式提交
                    tx.Commit();
                }
            }
        }

至此,利用C#通过NHibernate连接Oracle实现添加功能已经实现,增删改查原理类似。

除本文外:还可参考文档:https://nhibernate.info/doc/tutorials/first-nh-app/your-first-nhibernate-based-application.html 

 7.添加结果:

可查看插入的SQL语句:

猜你喜欢

转载自blog.csdn.net/qq_42539194/article/details/107961021