2009-07-20 36 views
11

Tôi đang sử dụng DDD và NHibernate để duy trì đối tượng miền của mình. Trong cơ sở dữ liệu của tôi, mỗi bảng có liên quan đến một thực thể có bốn cột phụ (CreatedBy, UpdateBy, CreatedDate, UpdateDate) được sử dụng để theo dõi kiểm toán. Tôi đang sử dụng mẫu kho lưu trữ mà chỉ cho phép lưu trữ tổng hợp các gốc. Khi NHibernate cố gắng lưu các thực thể trên gốc tổng hợp, tôi nhận được một lỗi SQL DateTime vì các thực thể không có thuộc tính kiểm toán của họ được thiết lập. Có cách nào trong NHibernate để thiết lập các thuộc tính trên các đối tượng ngay trước khi lưu?Thuộc tính thiết lập NHibernate tự động khi lưu

Dưới đây là một ví dụ nhỏ. Tôi có một đối tượng Order là gốc tổng hợp. Tôi cũng có các đối tượng OrderNote là con của đơn đặt hàng. Khi tôi thêm một OrderNote vào thứ tự và sau đó lưu thứ tự một ngoại lệ được ném bởi vì CreatedDate/UpdatedDate được thiết lập để DateTime.MinValue mà sẽ gây ra một tràn DateTime SQL. Vì các cột kiểm tra này là một phần của sự kiên trì và không liên quan đến miền vấn đề, tôi không muốn gốc tổng hợp Order để thiết lập các thuộc tính này khi ghi chú được thêm vào. Các cột/thuộc tính kiểm tra chỉ nên được biết bởi khuôn khổ kiên trì chứ không phải miền. Tôi muốn có thể nói với NHibernate để thiết lập các thuộc tính này khi lưu hoặc cập nhật. Có cách nào để làm việc này không?

Trả lời

11

Máy đánh chặn có thể thực hiện việc này:

http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-interceptors (9.10, liên kết không phải lúc nào cũng hoạt động).

Cắt/dán từ tài liệu:

public class AuditInterceptor : IInterceptor 
{ 
    ... 

    public boolean OnSave(object entity, 
          object id, 
          object[] state, 
          string[] propertyNames, 
          IType[] types) 
    { 
     if (entity is IAuditable) 
     { 
      for (int i=0; i<propertyNames.Length; i++) 
      { 
       if ("CreateTimestamp" == propertyNames[i]) 
       { 
        state[i] = DateTime.Now; 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

} 

OnFlushDirty() có thể được sử dụng cho UpdatedDate.

Bạn sẽ muốn mọi thực thể có một CreatedDate/UpdatedDate để thực hiện một giao diện để máy đánh chặn có thể kiểm tra xem nó có nên hoạt động hay không (trong ví dụ được cung cấp là IAuditable).


Sửa

Chỉ cần nhận thấy chương 11: đánh chặn và các sự kiện. Bạn có thể kế thừa từ EmptyInterceptor mà làm cho mọi thứ dễ dàng hơn nếu bạn chỉ cần ghi đè lên một số phương thức.

Tôi chưa bao giờ sử dụng Sự kiện.

+0

Tuyệt vời. Đó chính xác là những gì tôi đang tìm kiếm. Tôi mới sử dụng NHibernate và không biết tính năng này. Tôi có giao diện IAuditable được triển khai với các thuộc tính được bảo vệ để miền không thể nhìn thấy chúng. – awilinsk

1

Bạn cũng có thể xem xét hệ thống phiên bản của NHibernate, có thể giúp bạn trong trường hợp của bạn;)

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