NHibernate - Mapeamento de Tipos de Dados
Neste capítulo, abordaremos os tipos de dados de mapeamento. O mapeamento de entidades é direto, as classes de entidade são sempre mapeadas para tabelas de banco de dados usando<class>, <subclass>, and <joined-subclass>elementos de mapeamento. Os tipos de valor precisam de algo mais, que é onde os tipos de mapeamento são necessários.
O NHibernate é capaz de mapear uma ampla variedade de tipos de dados. Aqui está a lista dos tipos de dados mais comuns que são suportados.
Tipo de mapeamento | Tipo .NET | System.Data.DbType |
---|---|---|
Int16 | System.Int16 | DbType.Int16 |
Int32 | System.Int32 | DbType.Int32 |
Int64 | System.Int64 | DbType.Int64 |
solteiro | System.Single | DbType.Single |
em dobro | System.Double | DbType.Double |
Decimal | System.Decimal | DbType.Decimal |
Corda | System.String | DbType.String |
AnsiString | System.String | DbType.AnsiString |
Byte | System.Byte | DbType.Byte |
Caracteres | System.Char | DbType.StringFixedLength - um caractere |
AnsiChar | System.Char | DbType.AnsiStringFixedLength - um caractere |
boleano | System.Boolean | DbType.Boolean |
Guid | System.Guid | DbType.Guid |
PersistentEnum | System.Enum (uma enumeração) | DbType para o valor subjacente |
Verdadeiro falso | System.Boolean | DbType.AnsiStringFixedLength - 'T' ou 'F' |
Sim não | System.Boolean | DbType.AnsiStringFixedLength - 'Y' ou 'N' |
Data hora | Data hora | DbType.DateTime — ignora milissegundos |
Carrapatos | System.DateTime | DbType.Int64 |
Intervalo de tempo | System.TimeSpan | DbType.Int64 |
Timestamp | System.DateTime | DbType.DateTime - tão específico quanto o banco de dados suporta |
Binário | System.Byte [] | DbType.Binary |
BinaryBlob | System.Byte [] | DbType.Binary |
StringClob | System.String | DbType.String |
Serializável | Qualquer System.Object marcado com SerializableAttribute | DbType.Binary |
CultureInfo | System.Globalization.CultureInfo | DbType.String - cinco caracteres para cultura |
Tipo | Tipo de sistema | DbType.String contendo o nome qualificado do assembly |
A tabela fornecida acima explica em detalhes as dicas abaixo mencionadas.
Tudo, desde tipos numéricos simples a strings, que podem ser mapeados de várias maneiras usando varchars, chars etc., bem como blobs de string e toda a variedade de tipos que os bancos de dados suportam.
Também é capaz de mapear Booleans, para campos que usam zeros e uns, campos de caracteres que contêm verdadeiro, falso ou T e F.
Há uma grande variedade de maneiras de definir como isso mapeia para os valores booleanos de backend no banco de dados.
Podemos lidar com o mapeamento de DateTime, incluindo e excluindo compensações de fuso horário, horário de verão, etc.
Também podemos mapear enumerations; podemos mapeá-los para strings ou para seus valores numéricos subjacentes.
Vamos dar uma olhada em um exemplo simples no qual temos os mesmos nomes de propriedades no banco de dados e na classe Aluno.
Agora vamos mudar o FirstMidName para FirstName na classe do aluno, onde não mudaremos a coluna FirstMidName, mas veremos como informar ao NHibernate para realizar esta conversão. A seguir está a classe do aluno atualizada.
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; }
}
}
Aqui está a implementação do arquivo de mapeamento 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>
Neste exemplo, suponha que o campo FirstName seja uma string .NET e a coluna FirstMidName seja um SQL nvarchar. Agora, para dizer ao NHibernate como realizar essa conversão, defina o nome igual aFirstName e coluna igual a FirstMidName e especifique o tipo de mapeamento igual a String, que é apropriado para esta conversão particular.
O seguinte é um Program.cs implementação de arquivo.
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();
}
}
}
}
Agora, ao executar seu aplicativo, você verá a seguinte saída.
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
Como você pode ver, ele mapeou o nome da propriedade diferente para o nome da coluna no banco de dados.
Vamos dar uma olhada em outro exemplo em que adicionaremos outra propriedade na classe Aluno de enumtipo. Aqui está a implementação da classe Aluno.
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
}
}
Como você pode ver, essa enumeração tem uma variedade de valores diferentes que pode ter, como Excelente, Bom, Regular, Ruim e Péssimo.
Saltando para o arquivo de mapeamento, você pode ver que cada uma dessas propriedades está listada no arquivo de mapeamento, incluindo o recém-adicionado AcademicStanding propriedade.
<?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>
Agora também precisamos alterar o banco de dados, então vá para o SQL Server Object Explorer, clique com o botão direito do mouse no banco de dados e selecione a opção New Query….
Isso abrirá o editor de consultas e, em seguida, especificará a consulta abaixo.
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)
);
Esta consulta eliminará primeiro a tabela do aluno existente e, em seguida, criará uma nova tabela.
Clique no ícone Executar conforme mostrado acima. Assim que a consulta for executada com sucesso, você verá uma mensagem.
Expanda o banco de dados e a lista suspensa Tabela, clique com o botão direito do mouse na mesa do Aluno e selecione Exibir Designer.
Agora, você verá a tabela recém-criada, que também possui a nova propriedade AcademicStanding.
Vamos adicionar dois registros, conforme mostrado a seguir Program.cs Arquivo.
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();
}
}
}
}
Agora vamos executar seu aplicativo e você verá a seguinte saída na janela do console.
Fetch the complete list again
1 Allan Bommer Excellent
2 Jerry Lewis Good
Agora vamos dar uma olhada no banco de dados clicando com o botão direito do mouse na Tabela do Aluno.
Selecione Exibir dados e você verá os dois registros na tabela do aluno, conforme mostrado na captura de tela a seguir.
Você pode ver que dois registros são adicionados e Allan tem AcademicStanding 0 e Jerry tem AcademicStanding 1. Isso ocorre porque em .Net o primeiro valor de enumeração por padrão tem 0, que é excelente se você olhar StudentAcademicStanding. Enquanto no arquivo Student.cs Good é o segundo, ele tem o valor 1.