2009-03-09 23 views
9

Tôi đang xem lại và triển khai lại mã đã khiến tôi yêu cầu this question về kiểm tra dữ liệu trong NHibernate. Tuy nhiên thời gian này, tôi muốn đi với Sean Carpenter 's suggestion và triển khai ISaveOrUpdateEventListener (mới trong NHibernate 2.x)Kiểm tra dữ liệu trong NHibernate bằng các sự kiện

Tôi muốn thêm một hàng trong cơ sở dữ liệu cho mỗi thay đổi cho mỗi thuộc tính với giá trị cũ và mới vì vậy sau này trong giao diện người dùng, tôi có thể nói các nội dung như "Người dùng Bob đã thay đổi thuộc tính Wibble từ A thành B vào ngày 9 tháng 3 năm 2009 lúc 21:04"

Cách tốt nhất để so sánh trạng thái đối tượng là gì các thuộc tính của đối tượng đã thay đổi?

Bạn có thể nhận được trạng thái nạp của đối tượng bằng cách như sau:

public void OnSaveOrUpdate(SaveOrUpdateEvent saveOrUpdateEvent) 
    { 
     object[] foo = saveOrUpdateEvent.Entry.LoadedState; 
    } 

Và tôi cho rằng tôi có thể sử dụng phản ánh để làm việc ra mà thuộc tính đã thay đổi, nhưng tôi đã được đào bới xung quanh và có doesn' t dường như là một tập hợp các thuộc tính để so sánh. Tôi đã nghĩ rằng sẽ có một phương thức GetChangedProperties() hoặc một cái gì đó.

Tôi luôn có thể lấy đối tượng cũ từ cơ sở dữ liệu như nó và so sánh nó, nhưng đó lại là một cơ sở dữ liệu khác và có vẻ nặng nề trong kịch bản này.

Hướng tốt nhất để thực hiện điều này là gì?

P.S. Trong trường hợp nó tạo ra bất kỳ sự khác biệt nào, đây là một dự án ASP.NET-MVC/S # arp Architecture.

Trả lời

6

Tôi sẽ không biết cách đạt được những gì bạn muốn với giao diện ISaveOrUpdateListener - tuy nhiên bạn có thể tận dụng lợi thế của thực tế là giao diện IPreUpdateEventListenerIPreInsertEventListener đều cung cấp những gì bạn cần ... ví dụ: làm điều gì đó như sau:

public bool OnPreUpdate(PreUpdateEvent evt) 
{ 
    string[] names = evt.Persister.PropertyNames; 
    for(int index = 0; index < names.Length; index++) 
    { 
     // compare evt.State[index] to evt.OldState[index] and get 
     // the name of the changed property from 'names' 
     // (...) 
    } 
} 

và thực hiện tương tự cho việc chèn trước.

+0

này đã làm việc cho tôi. Cảm ơn mookid. –

+0

Cảm ơn "và lấy tên của thuộc tính đã thay đổi từ 'tên'". Tôi đã ở trên mạng trong 15 phút tìm kiếm một cách đáng tin cậy để đối sánh đối tượng với các giá trị. – SamuelKDavis

0

Bạn có thể triển khai mẫu Memento để tuần tự hóa trạng thái từ Tải ban đầu, qua ILoadEventListener. Rõ ràng bạn không muốn lưu trữ bộ sưu tập/mối quan hệ hoặc bạn muốn sao chép toàn bộ đồ thị đối tượng. Sau đó, bạn có thể lấy thông tin này ra và so sánh trong ISaveOrUpdateEventListener của mình.

11

Bạn cũng có thể sử dụng phương pháp FindDirty trên Persister để cho NHibernate làm sự so sánh cho bạn:

var dirtyFieldIndexes = @event.Persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session); 

foreach (var dirtyFieldIndex in dirtyFieldIndexes) 
{ 
    var oldValue = @event.OldState[dirtyFieldIndex]; 
    var newValue = @event.State[dirtyFieldIndex]; 

    // Log values to new "AuditLog" object and save appropriately. 
} 
+0

tất cả các loại tuyệt vời! –

Các vấn đề liên quan