2010-04-06 6 views
13

Tôi hiện đang phát triển một ứng dụng có kích thước trung bình, sẽ truy cập 2 hoặc nhiều cơ sở dữ liệu SQL, trên các trang ...Sử dụng mô hình Kho lưu trữ chung với thông thạo nHibernate

Tôi đang xem xét việc sử dụng một cái gì đó tương tự như sau: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

Tuy nhiên, tôi muốn sử dụng thành thạo nHibernate, ở vị trí của LINQ-to-SQL (và dĩ nhiên nHibernate.Linq)

đây có phải là khả thi?

Tôi sẽ định cấu hình điều này như thế nào? Định nghĩa ánh xạ của tôi sẽ ở đâu, v.v ...?

Ứng dụng này cuối cùng sẽ có nhiều khía cạnh - từ WebUI, Thư viện WCF và các ứng dụng/dịch vụ Windows.

Ngoài ra, ví dụ về một bảng "sản phẩm", tôi sẽ tạo ra một lớp "ProductManager", mà có phương pháp như:

GetProduct, GetAllProducts vv ...

Bất kỳ con trỏ đang nhận được rất nhiều.

+7

Chỉ cần một sidenote: NHibernate thông thạo chỉ là một cách để cấu hình ánh xạ NHibernate; nó không phải là một khung công tác khác và nó không liên quan gì đến việc triển khai kho lưu trữ. –

Trả lời

22

Theo ý kiến ​​của tôi (và trong một số ý kiến ​​của người khác), kho lưu trữ phải là một giao diện ẩn truy cập dữ liệu trong giao diện bắt chước giao diện bộ sưu tập. Đó là lý do tại sao một kho lưu trữ phải là một IQueryable và IEnumerable.

public interface IRepository<T> : IQueryable<T> 
{ 
    void Add(T entity); 
    T Get(Guid id); 
    void Remove(T entity); 
} 

public class Repository<T> : IQueryable<T> 
{ 
    private readonly ISession session; 

    public Repository(ISession session) 
    { 
    session = session; 
    } 

    public Type ElementType 
    { 
    get { return session.Query<T>().ElementType; } 
    } 

    public Expression Expression 
    { 
    get { return session.Query<T>().Expression; } 
    } 

    public IQueryProvider Provider 
    { 
    get { return session.Query<T>().Provider; } 
    } 

    public void Add(T entity) 
    { 
    session.Save(entity); 
    } 

    public T Get(Guid id) 
    { 
    return session.Get<T>(id); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
    return this.GetEnumerator(); 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
    return session.Query<T>().GetEnumerator(); 
    } 

    public void Remove(T entity) 
    { 
    session.Delete(entity); 
    } 
} 

Tôi không thực hiện phương thức SubmitChanges như trong kho lưu trữ, vì tôi muốn gửi các thay đổi của một số kho được sử dụng bởi một hành động của người dùng cùng một lúc. Tôi giấu công tác quản lý giao dịch trong một đơn vị của giao diện làm việc:

public interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
    void RollBack(); 
} 

tôi sử dụng phiên của một đơn vị cụ thể NHibernate thực hiện công việc như phiên cho các kho:

public interface INHiberanteUnitOfWork : IUnitOfWork 
{ 
    ISession Session { get; } 
} 

Trong một ứng dụng thực tế, tôi sử dụng một giao diện kho lưu trữ phức tạp hơn với các phương thức cho những thứ như phân trang, tải háo hức, mẫu đặc tả, truy cập vào các cách truy vấn khác được sử dụng bởi NHiberante thay vì chỉ là LINQ. Việc thực hiện LINQ trong thân cây NHibernate hoạt động tốt đủ cho hầu hết các truy vấn tôi cần phải làm.

+0

Brilliant! Đơn giản, IQueryable và một đơn vị công việc. Điều đó thực sự phù hợp với mẫu lưu trữ "Định nghĩa đối tượng miền trong bộ nhớ [...]". Thêm một số DI và nó thực sự có thể sử dụng được!Công việc tốt - :) – maxbeaudoin

+2

Chúng ta có thể thấy "giao diện kho lưu trữ phức tạp hơn" trông như thế nào không? Điều này là tốt nhưng tôi cũng muốn để có thể làm "những thứ như pagination, tải háo hức, mô hình đặc điểm kỹ thuật, truy cập vào các cách khác của truy vấn được sử dụng bởi NHiberante thay vì chỉ linq". Ngoài ra, nó sẽ rất hữu ích nếu bạn có thể chứng minh làm thế nào bạn đang sử dụng nó. Cảm ơn trước! – W3Max

+0

Tôi tò mò cũng như cách bạn định nghĩa IRepository để tận dụng lợi thế của các phương thức truy vấn khác với NHibernate - trong khi vẫn giữ nó chung chung. –

1

Dưới đây là suy nghĩ của tôi về kho chung:

Advantage of creating a generic repository vs. specific repository for each object?

Tôi đã sử dụng thành công mô hình đó với NHibernate, và đã không tìm thấy bất kỳ thiếu sót thực sự.

Gợi ý là kho lưu trữ thực sự chung chung là một chút của cá trích đỏ, nhưng lợi ích tương tự có thể được thực hiện bằng cách suy nghĩ về vấn đề hơi khác nhau.

Hy vọng điều đó sẽ hữu ích.