2009-10-07 47 views
5

Tôi mới dùng NHibernate (và ORMS) và cố gắng nắm bắt được vô số các tùy chọn khác nhau mà nó trình bày. Để tham khảo, tôi đang sử dụng Fluent NHibernate với các đối tượng kinh doanh riêng biệt mà lần lượt sử dụng DTO hoàn toàn cho truy cập dữ liệu. Kiến trúc ứng dụng của tôi phải hỗ trợ cả hai cửa sổ và web "giao diện người dùng".Cách tiếp cận tốt nhất để xây dựng NHibernate DTO's

Việc quấy rối của tôi là một trong những cách tiếp cận chung vì dường như có rất nhiều tùy chọn. DTO của tôi trông giống như mẫu dưới đây. Mỗi DTO có một tham chiếu đến một ISession được chuyển cho chúng từ BO. Họ có trách nhiệm tải của mình và tiết kiệm:

public class EmployeeDTO... 

    // Data Properties to be persisted to the database 
    public virtual int Id { get; private set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual ISession Session { get; set; } 

    // Save logic 
    public virtual void Save() 
    { 
     var transaction = Session.BeginTransaction(); 
     Session.SaveOrUpdate(this); 
     transaction.Commit(); 
    } 

    // Load logic 
    public virtual void Load(int id)... 

Trước hết: Đây có phải là cách tiếp cận đúng để có - nên DTO có khả năng lưu và tải bản thân?

Thứ hai: Bất kể nơi lưu/code tải nằm, bạn nên sử dụng cùng một ISession cho các đời hoặc một đối tượng, hoặc họ cần phải có một ref đến ISessionFactory và mở một phiên mới mọi tương tác cơ sở dữ liệu thời gian bắt buộc?

// Open a new session every time I interact with the repository 
    var session = FluentSupport.SessionFactory.OpenSession(); 
    var transaction = Session.BeginTransaction(); 
    Session.SaveOrUpdate(this); 
    transaction.Commit(); 
    session.Close(); 
    // Close the session when I'm done 

Tất nhiên luôn có phương án 3, không có ở trên :)

+0

Khi một đối tượng biết cách Lưu chính nó được gọi là DAO, điều này không liên quan gì đến DTO –

Trả lời

10

Nói chung, DTOs không chứa hành vi (như Save, Load) và không chứa kiến ​​thức về cách họ nhận được vẫn kiên trì (ISession). Có vẻ như những gì bạn đang thực sự tạo ra là một lớp dữ liệu. Lớp kinh doanh của bạn lý tưởng không nên biết về ISession. Điều đó nói rằng, bạn có thể tắt lớp này tất cả những gì bạn muốn vì nó phù hợp với nhu cầu của bạn, nhưng có thể sẽ khó thay đổi thành ORM khác sau này nếu ORM của bạn chảy máu qua tất cả các lớp của bạn.

Để quản lý tuổi thọ ISession, bạn phải quyết định xem bạn sẽ sử dụng mẫu UnitOfWork, về cơ bản, mọi yêu cầu của người dùng đều nhận được ISession mới. Có những lựa chọn khác cho ISession suốt đời và bạn thực sự không bị giới hạn trong vấn đề đó. Thông thường, có thể có các phương pháp hay nhất xung quanh ứng dụng web so với ứng dụng trên cửa sổ so với bất kỳ loại ứng dụng nào khác, nhưng bạn không chỉ định những gì bạn đang viết.

+0

cấu trúc có hỗ trợ cả web (Silverlight) và cửa sổ (WPF) – Steve

+0

Tôi đã làm rõ câu hỏi để giải quyết vấn đề này. .. – Steve

2

ISession rất rẻ để mở/đóng. Các vấn đề với việc giữ nó mở quá lâu là hồ bơi kết nối không thể tái sử dụng kết nối cho đến khi nó lần ra hoặc những gì không. Điều này có thể là một vấn đề trong một ứng dụng đa người dùng.

Trong trường hợp của bạn, tôi có thể đi theo hướng dịch vụ theo định hướng để lưu trữ dữ liệu truy xuất. có nghĩa là DTO sẽ chỉ được sử dụng trong nội bộ trong các ranh giới dịch vụ. Nếu bạn cần phải sao chép các đối tượng trông giống nhau tôi đề nghị bạn có một cái nhìn tại AutoMapper được tạo ra cho mục đích cụ thể này. Nếu bạn chỉ có một cửa sổ hoặc dự án chỉ web thì đó không phải là vấn đề. Đó là khi bạn trộn. Bạn không thể xử lý các phiên theo cùng một cách trong ứng dụng Windows như trong một ứng dụng Web.

9

Giữ mã tải/tiết kiệm riêng biệt với DTO của bạn. Đối tượng DTO chỉ là lượt xem của dữ liệu cơ bản.

Khi thực hiện truy vấn của bạn, hãy trả lại DTO bằng cách sử dụng phép chuyển đổi. Một cái gì đó như thế này:

resultSet = session.CreateCriteria(typeof(MyDataObject)) 
    .Add(query criteria, etc.) 
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>()) 
    .List<IMyDTOObject>()
+0

Tôi có thể sử dụng tiêu chí nào trong phương pháp Thêm (để liên kết thuộc tính miền với thuộc tính DTO)? –

+0

@SilvioDelgado: Tôi xin lỗi, tôi đã không làm việc với NHibernate trong hơn 3 năm, vì vậy tôi không biết. –

+0

Không sao cả. Cảm ơn bạn anyway. :) –

3

DTO có nghĩa là "đối tượng chuyển dữ liệu". Đó là, các đối tượng câm được sử dụng để truyền các giá trị hoặc các tập hợp các giá trị xung quanh trong hệ thống của bạn. Họ không nên chịu trách nhiệm cho sự bền bỉ bản thân, hoặc thậm chí bản đồ 1-1 cho các đối tượng miền trong lớp miền của bạn.

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