NHibernate - 数据类型映射


在本章中,我们将讨论映射数据类型。映射实体很简单,实体类始终使用<class>、<subclass> 和 <joined-subclass>映射元素映射到数据库表。值类型还需要更多东西,这就是需要映射类型的地方。

NHibernate 能够映射多种数据类型。以下是支持的最常见数据类型的列表。

映射类型 .NET类型 系统.数据.Db类型
整数16 系统.Int16 DbType.Int16
整数32 系统.Int32 DbType.Int32
整型64 系统.Int64 DbType.Int64
单身的 系统.单一 数据库类型.Single
双倍的 系统.双 DbType.Double
十进制 系统.十进制 DbType.Decimal
细绳 系统字符串 数据库类型.字符串
Ansi字符串 系统字符串 DbType.AnsiString
字节 系统字节 数据库类型.Byte
查尔 系统字符 DbType.StringFixedLength - 一个字符
安西查尔 系统字符 DbType.AnsiStringFixedLength — 一个字符
布尔值 系统布尔值 DbType.布尔值
指导 系统指南 数据库类型.Guid
持久枚举 System.Enum(枚举) 基础值的 DbType
真假 系统布尔值 DbType.AnsiStringFixedLength - “T”或“F”
是 否 系统布尔值 DbType.AnsiStringFixedLength - “Y”或“N”
约会时间 约会时间 DbType.DateTime—忽略毫秒
蜱虫 系统日期时间 DbType.Int64
时间跨度 系统时间跨度 DbType.Int64
时间戳 系统日期时间 DbType.DateTime — 与数据库支持的具体程度相同
二进制 系统字节[] DbType.Binary
二进制Blob 系统字节[] DbType.Binary
字符串块 系统字符串 数据库类型.字符串
可串行化 任何标有 SerializedAttribute 的 System.Object DbType.Binary
文化资讯 系统.全球化.文化信息 DbType.String — 五个文化字符
类型 系统类型 DbType.String 保存程序集限定名称

上面给出的表格详细解释了下面提到的指针。

  • 从简单的数字类型到字符串,可以使用varchar、char等以多种方式映射,以及字符串 blob 和数据库支持的所有类型。

  • 它还能够将布尔值映射到使用零和一的字段、包含 true、false 或 T 和 F 的字符字段。

  • 有多种方法可以定义如何映射到后端数据库中的布尔值。

  • 我们可以处理DateTime的映射,包括和排除时区偏移、夏令时等。

  • 我们还可以映射枚举;我们可以将它们映射到字符串或其基础数值。

让我们看一个简单的示例,其中数据库和 Student 类中都有相同的属性名称。

现在让我们在学生类中将 FirstMidName 更改为 FirstName,其中我们不会更改 FirstMidName 列,但我们将了解如何告诉 NHibernate 知道执行此转换。以下是更新后的学生班级。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;

namespace NHibernateDemoApp { 
  
   class Student { 
      public virtual int ID { get; set; } 
      public virtual string LastName { get; set; } 
      public virtual string FirstName { get; set; } 
   }
}

这里是NHibernate映射文件的实现。

<?xml version = "1.0" encoding = "utf-8" ?> 
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemoApp" 
   namespace = "NHibernateDemoApp"> 
   
   <class name = "Student">
	
      <id name = "ID"> 
         <generator class = "native"/>
      </id> 
   
      <property name = "LastName"/> 
      <property name = "FirstName" column = "FirstMidName" type = "String"/> 
   </class> 

</hibernate-mapping>

在此示例中,假设 FirstName 字段是 .NET 字符串,FirstMidName 列是SQL nvarchar。现在要告诉 NHibernate 如何执行此转换,请将名称设置为FirstName,将列设置为FirstMidName,并指定映射类型等于 String,这适合此特定转换。

以下是Program.cs文件的实现。

using HibernatingRhinos.Profiler.Appender.NHibernate; 
using NHibernate.Cfg; 
using NHibernate.Dialect; 
using NHibernate.Driver; 

using System; 
using System.Linq; 
using System.Reflection;

namespace NHibernateDemoApp { 

   class Program { 
	
      static void Main(string[] args) { 
		
         NHibernateProfiler.Initialize(); 
         var cfg = new Configuration(); 
			
         String Data Source = asia13797\\sqlexpress;
         String Initial Catalog = NHibernateDemoDB;
         String Integrated Security = True;
         String Connect Timeout = 15;
         String Encrypt = False;
         String TrustServerCertificate = False;
         String ApplicationIntent = ReadWrite;
         String MultiSubnetFailover = False;
         
         cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + 
            Initial Catalog + Integrated Security + Connect Timeout + Encrypt +
            TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; 
            
            x.Driver<SqlClientDriver>(); 
            x.Dialect<MsSql2008Dialect>(); 
            x.LogSqlInConsole = true; 
         }); 
         
         cfg.AddAssembly(Assembly.GetExecutingAssembly()); 
         var sefact = cfg.BuildSessionFactory();
			
         using (var session = sefact.OpenSession()) { 
            
            using (var tx = session.BeginTransaction()) { 
               var students = session.CreateCriteria<Student>().List<Student>(); 
               Console.WriteLine("\nFetch the complete list again\n"); 
               
               foreach (var student in students) { 
                  Console.WriteLine("{0} \t{1} \t{2}", student.ID, student.FirstName,
                     student.LastName); 
               } 
					
               tx.Commit(); 
            } 
				
            Console.ReadLine(); 
         } 
      } 
   }
}

现在,当您运行应用程序时,您将看到以下输出。

NHibernate: SELECT this_.ID as ID0_0_, this_.LastName as LastName0_0_, 
   this_.FirstMidName as FirstMid3_0_0_ FROM Student this_

Fetch the complete list again
3 Allan Bommer
4 Jerry Lewis

正如您所看到的,它已将不同的属性名称映射到数据库中的列名称。

让我们看另一个例子,我们将在枚举类型的 Student 类中添加另一个属性。这是 Student 类的实现。

using System; 
using System.Collections.Generic; 
using System.Linq; using System.Text; 
using System.Threading.Tasks; 

namespace NHibernateDemoApp { 
   
   class Student { 
      public virtual int ID { get; set; } 
      public virtual string LastName { get; set; } 
      public virtual string FirstName { get; set; } 
      public virtual StudentAcademicStanding AcademicStanding { get; set; } 
   } 
   
   public enum StudentAcademicStanding { 
      Excellent, 
      Good, 
      Fair, 
      Poor, 
      Terrible 
   } 
}

正如您所看到的,枚举具有多种不同的值,例如 Excellent、Good、Fair、Poor 和 Terrible。

跳转到映射文件,您可以看到每个属性都在映射文件中列出,包括新添加的AcademicStanding属性。

<?xml version = "1.0" encoding = "utf-8" ?> 
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" 
   assembly = "NHibernateDemoApp" namespace = "NHibernateDemoApp"> 
   
   <class name = "Student"> 
	
      <id name = "ID"> 
         <generator class = "native"/> 
      </id> 

      <property name = "LastName"/> 
      <property name = "FirstName" column = "FirstMidName" type = "String"/> 
      <property name = "AcademicStanding"/> 
   </class>  

</hibernate-mapping>

现在我们还需要更改数据库,因此转到 SQL Server 对象资源管理器并右键单击数据库并选择“新建查询...”选项。

新查询

它将打开查询编辑器,然后指定以下查询。

DROP TABLE [dbo].[Student]

CREATE TABLE [dbo].[Student] ( 
   [ID] INT IDENTITY (1, 1) NOT NULL, 
   [LastName] NVARCHAR (MAX) NULL, 
   [FirstMidName] NVARCHAR (MAX) NULL, 
   [AcademicStanding] NCHAR(10) NULL, 
   CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC) 
);

该查询将首先删除现有的学生表,然后创建一个新表。

创建新表

单击“执行”图标,如上所示。查询成功执行后,您会看到一条消息。

展开数据库和表下拉列表,然后右键单击 Student 表并选择视图设计器。

表格下拉列表

现在,您将看到新创建的表,它还具有新属性AcademicStanding。

学术地位

让我们添加两条记录,如以下Program.cs文件中所示。

using HibernatingRhinos.Profiler.Appender.NHibernate; 
using NHibernate.Cfg; 
using NHibernate.Dialect; 
using NHibernate.Driver; 

using System; 
using System.Linq; 
using System.Reflection;

namespace NHibernateDemoApp { 

   class Program { 
      
      static void Main(string[] args) { 
		
         NHibernateProfiler.Initialize(); 
         var cfg = new Configuration(); 
			
         String Data Source = asia13797\\sqlexpress;
         String Initial Catalog = NHibernateDemoDB;
         String Integrated Security = True;
         String Connect Timeout = 15;
         String Encrypt = False;
         String TrustServerCertificate = False;
         String ApplicationIntent = ReadWrite;
         String MultiSubnetFailover = False;
         
         cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + 
            Initial Catalog + Integrated Security + Connect Timeout + Encrypt +
            TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; 
            
            x.Driver<SqlClientDriver>(); 
            x.Dialect<MsSql2008Dialect>(); 
         }); 
         
         cfg.AddAssembly(Assembly.GetExecutingAssembly()); 
         var sefact = cfg.BuildSessionFactory(); 
         
         using (var session = sefact.OpenSession()) { 
            using (var tx = session.BeginTransaction()) { 
               
               var student1 = new Student { 
                  ID = 1, 
                  FirstName = "Allan", 
                  LastName = "Bommer",
                  AcademicStanding = StudentAcademicStanding.Excellent 
               };
               
               var student2 = new Student { 
                  ID = 2, 
                  FirstName = "Jerry", 
                  LastName = "Lewis", 
                  AcademicStanding = StudentAcademicStanding.Good 
               };
					
               session.Save(student1); 
               session.Save(student2);
               var students = session.CreateCriteria<Student>().List<Student>(); 
               Console.WriteLine("\nFetch the complete list again\n");
               
               foreach (var student in students) { 
                  Console.WriteLine("{0} \t{1} \t{2} \t{3}", student.ID,
                     student.FirstName, student.LastName, student.AcademicStanding); 
               } 
					
               tx.Commit(); 
            }
				
            Console.ReadLine(); 
         } 
      } 
   } 
}

现在让我们运行您的应用程序,您将在控制台窗口上看到以下输出。

Fetch the complete list again

1 Allan Bommer Excellent
2 Jerry Lewis Good

现在让我们通过右键单击“学生表”来查看数据库。

数据库

选择“查看数据”,您将看到学生表中的两条记录,如下图所示。

查看数据

您可以看到添加了两条记录,Allan 的AcademicStanding 为0,Jerry 的AcademicStanding 1。这是因为在.Net 中,默认情况下第一个枚举值是0,如果您查看StudentAcademicStanding ,这非常。而在 Student.cs 文件中 Good 是第二个,因此它的值为 1。