NHibernate - Thành phần ánh xạ
Trong chương này, chúng ta sẽ nói về các thành phần ánh xạ. Trong NHibernate,component is a value object. Nó không có một bản sắc riêng của nó.
Ví dụ về điều này sẽ là một vật thể tiền, một chiếc ví hoặc một chiếc ví có thể có tiền trong đó, nhưng danh tính chính xác của số tiền đó là không liên quan.
Nó không có khóa chính của riêng nó, nhưng bản thân các thành phần liên tục trong cùng một bảng với đối tượng sở hữu.
Hãy xem một ví dụ đơn giản trong đó một sinh viên có Địa chỉ, là đối tượng của Location class Liên kết với nó.
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 virtual Location Address { get; set; }
}
public class Location {
public virtual string Street { get; set; }
public virtual string City { get; set; }
public virtual string Province { get; set; }
public virtual string Country { get; set; }
}
public enum StudentAcademicStanding {
Excellent,
Good,
Fair,
Poor,
Terrible
}
}
Bây giờ, chúng ta cũng cần cập nhật cơ sở dữ liệu bằng cách thực hiện truy vấn sau, truy vấn này trước tiên sẽ thả bảng Sinh viên và sau đó tạo một bảng mới cũng sẽ chứa một cột cho lớp Vị trí.
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,
[Street] NVARCHAR (100) NULL,
[City] NVARCHAR (100) NULL,
[Province] NVARCHAR (100) NULL,
[Country] NVARCHAR (100) NULL,
CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC)
);
Bây giờ để ánh xạ những cột không trực tiếp là một phần của lớp Sinh viên, nhưng chúng là thuộc tính của lớp Vị trí và đối tượng lớp Vị trí được xác định trong lớp sinh viên. Chúng tôi cần một thành phần để ánh xạ nó một cách chính xác. Hãy tạo một thành phần trongstudent.hbm.xml tệp như được hiển thị trong mã sau.
<?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"/>
<component name = "Address">
<property name = "Street"/>
<property name = "City"/>
<property name = "Province"/>
<property name = "Country"/>
</component>
</class>
</hibernate-mapping>
Thành phần này là Địa chỉ và nó có các thuộc tính khác nhau trên đó. Với thông tin này, NHibernate hiện có đủ để nó thực sự có thể lập bản đồ này.
Bây giờ đây là tệp Program.cs trong đó một đối tượng sinh viên mới được tạo và khởi tạo, sau đó được lưu vào cơ sở dữ liệu. Sau đó, nó sẽ lấy danh sách từ cơ sở dữ liệu.
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cache;
using NHibernate.Caches.SysCache;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;
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.Poor,
Address = new Location {
Street = "123 Street",
City = "Lahore",
Province = "Punjab",
Country = "Pakistan"
}
};
session.Save(student1);
tx.Commit();
var students = session.Query<Student>().ToList<Student>();
Console.WriteLine("\nFetch the complete list again\n");
foreach (var student in students) {
Console.WriteLine("{0} \t{1} \t{2} \t{3} \t{4} \t{5} \t{6} \t{7}",
student.ID,
student.FirstName,
student.LastName,
student.AcademicStanding,
student.Address.Street,
student.Address.City,
student.Address.Province,
student.Address.Country
);
}
}
Console.ReadLine();
}
}
}
}
Bây giờ chúng ta có thể chạy ứng dụng này và NHibernate có thể lưu các giá trị đó vào cơ sở dữ liệu. Khi bạn chạy ứng dụng, bạn sẽ thấy kết quả sau.
Fetch the complete list again
2 Allan Bommer Poor 123 Street Lahore Punjab Pakistan
Đây là các giá trị trong cơ sở dữ liệu.
Các thành phần cho phép chúng ta tách các cột trong bảng cơ sở dữ liệu thành lớp riêng của chúng.
Điều khác cần lưu ý ở đây là bởi vì Vị trí là một lớp, nó không phải là một thực thể.
Nó là một đối tượng kiểu giá trị và nó không có khóa chính của riêng mình.
Nó được lưu trong cùng một bảng với Student chứa nó.
Đó là lý do tại sao chúng tôi sử dụng thành phần ở đây.
Điều này cho phép rất nhiều sự linh hoạt để thay đổi lớp lớp của chúng ta, cách các lớp của chúng ta được định nghĩa so với cách cơ sở dữ liệu của chúng ta được bố trí.