NHibernate - Bản đồ bộ sưu tập
Trong chương này, chúng tôi sẽ trình bày cách biểu diễn các tập hợp. Có nhiều loại bộ sưu tập khác nhau mà chúng tôi có thể sử dụng trong NHibernate, chẳng hạn như -
- Lists
- Sets
- Bags
Bây giờ, từ quan điểm .NET, chúng ta thường xử lý danh sách hoặc như các cấu trúc dữ liệu, danh sách, từ điển rất đơn giản. .NET không có nhiều loại tập hợp khác nhau. Vậy tại sao NHibernate lại cần tất cả các loại khác nhau này? Nó thực sự quay trở lại cơ sở dữ liệu.
Danh sách
Danh sách là một tập hợp các phần tử có thứ tự không nhất thiết phải là duy nhất.
Chúng tôi có thể lập bản đồ này bằng cách sử dụng IList <T>.
Vì vậy, mặc dù chúng ta có thể có một danh sách các địa chỉ theo quy ước và từ quan điểm ứng dụng, chúng ta biết rằng các phần tử là duy nhất, không có gì trong danh sách ngăn chúng ta chèn các phần tử trùng lặp vào danh sách đó.
Bộ
Tập hợp là một tập hợp các phần tử duy nhất không có thứ tự. Nếu bạn cố gắng chèn 2 phần tử trùng lặp vào một tập hợp, nó sẽ tạo ra một ngoại lệ.
Không có gì cụ thể trong NHibernate về nó.
Đó chỉ là một cách thuận tiện để có một triển khai tập hợp chung. Nếu bạn đang sử dụng .NET 4, bạn có thể sử dụngHashSet <T> để đại diện cho những điều này, nhưng trong hầu hết các ứng dụng NHibernate, chúng tôi khẳng định đây là một ISet.
Nó là một không có thứ tự, nếu bạn kéo lại danh sách các địa chỉ từ cơ sở dữ liệu hoặc danh sách các đơn đặt hàng, bạn sẽ không biết chúng đến theo thứ tự nào trừ khi bạn đặt trong một mệnh đề Order by cụ thể.
Vì vậy, nói chung, dữ liệu bạn đang lấy lại từ cơ sở dữ liệu là tập hợp.
Chúng là tập hợp các phần tử duy nhất không có thứ tự.
Túi
Một tập hợp phổ biến khác mà chúng ta sẽ thấy trong thế giới cơ sở dữ liệu là một túi, giống như một tập hợp ngoại trừ nó có thể có các phần tử trùng lặp.
Trong thế giới .NET, chúng tôi đại diện cho điều này bởi một IList.
Bộ có lẽ là phổ biến nhất, nhưng bạn sẽ thấy danh sách và túi cũng tùy thuộc vào ứng dụng của bạn. Chúng ta hãy xem xét một bên dướicustomer.hbm.xml từ chương cuối cùng, trong đó Đặt lệnh được xác định.
<?xml version = "1.0" encoding = "utf-8" ?>
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemo"
namespace = "NHibernateDemo">
<class name = "Customer">
<id name = "Id">
<generator class = "guid.comb"/>
</id>
<property name = "FirstName"/>
<property name = "LastName"/>
<property name = "AverageRating"/>
<property name = "Points"/>
<property name = "HasGoldStatus"/>
<property name = "MemberSince" type = "UtcDateTime"/>
<property name = "CreditRating" type = "CustomerCreditRatingType"/>
<component name = "Address">
<property name = "Street"/>
<property name = "City"/>
<property name = "Province"/>
<property name = "Country"/>
</component>
<set name = "Orders" table = "`Order`">
<key column = "CustomerId"/>
<one-to-many class = "Order"/>
</set>
</class>
</hibernate-mapping>
Như bạn có thể thấy, chúng tôi đã ánh xạ bộ sưu tập đơn đặt hàng thành một tập hợp. Hãy nhớ rằng một tập hợp là một tập hợp không có thứ tự của các phần tử duy nhất.
Bây giờ, nếu bạn nhìn vào lớp Khách hàng, bạn sẽ thấy thuộc tính Đơn hàng được định nghĩa bằng ISet như được hiển thị trong chương trình sau.
public virtual ISet<Order> Orders { get; set; }
Bây giờ khi ứng dụng này được chạy, bạn sẽ thấy kết quả sau.
New Customer:
John Doe (00000000-0000-0000-0000-000000000000)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Unspecified)
CreditRating: Good
AverageRating: 42.42424242
Orders:
Order Id: 00000000-0000-0000-0000-000000000000
Order Id: 00000000-0000-0000-0000-000000000000
Reloaded:
John Doe (1f248133-b50a-4ad7-9915-a5b8017d0ff1)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: c41af8f2-7124-42a7-91c5-a5b8017d0ff6
Order Id: 657f6bb0-1f42-45fc-8fc7-a5b8017d0ff7
The orders were ordered by:
John Doe (1f248133-b50a-4ad7-9915-a5b8017d0ff1)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: c41af8f2-7124-42a7-91c5-a5b8017d0ff6
Order Id: 657f6bb0-1f42-45fc-8fc7-a5b8017d0ff7
John Doe (1f248133-b50a-4ad7-9915-a5b8017d0ff1)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: c41af8f2-7124-42a7-91c5-a5b8017d0ff6
Order Id: 657f6bb0-1f42-45fc-8fc7-a5b8017d0ff7
Press <ENTER> to exit...
Nếu các mục trong bộ sưu tập không cần phải là duy nhất, nếu bạn có thể có nhiều đơn đặt hàng với cùng một khóa chính xảy ra nhiều lần trong bộ sưu tập này, thì điều này sẽ tốt hơn được ánh xạ dưới dạng túi như được hiển thị trong chương trình sau.
<bag name = "Orders" table = "`Order`">
<key column = "CustomerId"/>
<one-to-many class = "Order"/>
</bag>
Bây giờ, nếu bạn chạy ứng dụng này, bạn sẽ nhận được một ngoại lệ vì nếu chúng ta xem xét lớp khách hàng, bạn sẽ nhận thấy rằng các đơn đặt hàng được đánh dấu là ISet trong mã C #.
Vì vậy, chúng ta cũng sẽ cần thay đổi điều này thành IList và sau đó ở đây, chúng ta sẽ cần thay đổi từ HashSet thành Danh sách trong phương thức khởi tạo.
public class Customer {
public Customer() {
MemberSince = DateTime.UtcNow;
Orders = new List<Order>();
}
public virtual Guid Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual double AverageRating { get; set; }
public virtual int Points { get; set; }
public virtual bool HasGoldStatus { get; set; }
public virtual DateTime MemberSince { get; set; }
public virtual CustomerCreditRating CreditRating { get; set; }
public virtual Location Address { get; set; }
public virtual IList<Order> Orders { get; set; }
public virtual void AddOrder(Order order) { Orders.Add(order); order.Customer = this; }
public override string ToString() {
var result = new StringBuilder();
result.AppendFormat("{1} {2} ({0})\r\n\tPoints: {3}\r\n\tHasGoldStatus:
{4}\r\n\tMemberSince: {5} ({7})\r\n\tCreditRating: {6}\r\n\tAverageRating:
{8}\r\n", Id, FirstName, LastName, Points, HasGoldStatus, MemberSince,
CreditRating, MemberSince.Kind, AverageRating); result.AppendLine("\tOrders:");
foreach(var order in Orders) {
result.AppendLine("\t\t" + order);
}
return result.ToString();
}
}
Khi bạn chạy ứng dụng, bạn sẽ thấy hành vi tương tự. Tuy nhiên, bây giờ chúng ta có thể có một đơn đặt hàng xảy ra nhiều lần trong cùng một bộ sưu tập.
John Doe (00000000-0000-0000-0000-000000000000)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Unspecified)
CreditRating: Good
AverageRating: 42.42424242
Orders:
Order Id: 00000000-0000-0000-0000-000000000000
Order Id: 00000000-0000-0000-0000-000000000000
Reloaded:
John Doe (fbde48f5-d620-4d1c-9a7f-a5b8017c3280)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: 6dd7dbdb-354f-4c82-9c39-a5b8017c3286
Order Id: 9b3e2441-a81b-404d-9aed-a5b8017c3287
The orders were ordered by:
John Doe (fbde48f5-d620-4d1c-9a7f-a5b8017c3280)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: 6dd7dbdb-354f-4c82-9c39-a5b8017c3286
Order Id: 9b3e2441-a81b-404d-9aed-a5b8017c3287
John Doe (fbde48f5-d620-4d1c-9a7f-a5b8017c3280)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: 6dd7dbdb-354f-4c82-9c39-a5b8017c3286
Order Id: 9b3e2441-a81b-404d-9aed-a5b8017c3287
Press <ENTER> to exit...