2009-03-23 28 views
15

Lấy Enum Cờ sauMapping để một chút cờ Enum trong Nhibernate

[Flags] 
enum Permssions 
{ 
    CanComment = 1, 
    CanEdit = 2, 
    CanDelete = 4, 
    CanRemoveUsers = 8, 
    All = CanComment | CanEdit | CanDelete | CanRemoveUsers 
} 

Trong NHibernate Tôi đã ánh xạ tới một enum trước khi sử dụng:

<property type="n.Permssions, n.Permssions" 
name="Permssions" column="Permssions"></property> 

Câu hỏi của tôi là, làm thế nào để ánh xạ một trường bitwise vào trường Flag sử dụng NHibnerate?

Trả lời

2

Tôi nghĩ tùy chọn tốt nhất cho việc này là sử dụng Custom User Type. Trong đó bạn có thể ánh xạ Enum trong lớp của bạn với hai cột đó. Dưới đây là một ví dụ của việc sử dụng ICompositeUserMap mà có thể được sử dụng như một hướng dẫn:

Mặc dù trong trường hợp của bạn, chỉ cần thực hiện IUserType thể đủ.

+0

Không cần thiết cho loại người dùng tùy chỉnh - NHibernate biết cách xử lý enum Flags. Hãy xem câu trả lời hàng đầu. –

0

này không trả lời câu hỏi của bạn một cách chính xác, nhưng nó có thể được dễ dàng hơn để sử dụng một tài sản Int32 trong lớp và bản đồ của bạn, và sử dụng một lớp tĩnh của hằng số như thế này để xử lý các giá trị trong mã:

public static class Permissions 
{ 
    public const int CanComment = 0x1; 
    public const int CanEdit = 0x2; 
    public const int CanDelete = 0x4; 
    public const int CanRemoveUsers = 0x8; 
    public const int All = CanComment | CanEdit | CanDelete | CanRemoveUsers; 
} 

Tôi biết điều này không lý tưởng, vì nó không hạn chế người dùng của bạn với các giá trị enum cố định, và buộc bạn phải xử lý ints thô trong mã, nhưng tôi nghĩ Hibernate sẽ gặp rắc rối với một enum bitwise. Nó sẽ cố gắng ánh xạ một giá trị trong cơ sở dữ liệu trở lại một giá trị enum cụ thể. Nếu nó tìm thấy một giá trị trong cơ sở dữ liệu mà bạn chưa liệt kê rõ ràng nó có thể sẽ bị nghẹt thở. Ví dụ. nếu nó tìm thấy "3" trong cơ sở dữ liệu, nó sẽ không thể ánh xạ nó trở lại giá trị enum, trừ khi bạn liệt kê rõ ràng mọi kết hợp, như CanCommentAndEdit, CanCommentAndEditAndDelete, v.v. Điều này có thể đánh bại mục đích sử dụng bitum enum .

0

Tôi sẽ có trường int riêng tư cho độ bền NHibernate và thuộc tính công khai Getter/Setter cho enum cờ đọc và ghi vào trường int. (NHibernate có thể được cấu hình để làm việc với các trường riêng)

Bằng cách đó bạn không phải sử dụng ma thuật voodoo hoặc các hằng số lộn xộn để hoàn thành công việc.

9

Khi tôi ánh xạ một enum, và enum này có giá trị sao lưu kiểu 'int', tôi chỉ ánh xạ thuộc tính enum của tôi vào trường int trong cơ sở dữ liệu. Tôi đã không gặp vấn đề gì cho việc này.
Tôi cũng đã làm điều này để gắn cờ enums, và điều này chỉ hoạt động mà không có vấn đề gì. Khi bạn kết hợp các cờ nhất định, NHibernate sẽ tiếp tục 'kết hợp' các cờ đó thành cột được chỉ định trong cơ sở dữ liệu.
Khi bạn truy xuất thể hiện có thuộc tính 'cờ enums', NHibernate sẽ sao lưu lại kết hợp chính xác. Ví dụ:
Ví dụ, nếu DB chứa '3', thì NHibernate sẽ điền thuộc tính của bạn với sự kết hợp của các giá trị thích hợp.
Trong thực tế, tôi để cho NHibernate con số nó ra tất cả bởi chính mình:

<property name="OnCallType" column="OnCallType" /> 

nơi cột OnCallType là kiểu int trong DB của tôi, và tài sản OnCallType là một kiểu liệt kê có thuộc tính cờ.

+0

những gì về nhibernate ghosting ?? – giammin

1

Điều này giải quyết được sự cố cho tôi:

Trong ánh xạ lớp tôi đã ánh xạ nó thành loại tùy chỉnh có tên loại enum.

Map(x => x.MyEnumProperty).CustomType<EnumType>(); 
Các vấn đề liên quan