2010-05-06 27 views
8

Trong ngữ cảnh của ứng dụng n-tier, có sự khác biệt nào giữa những gì bạn sẽ xem xét các lớp truy cập dữ liệu và kho lưu trữ của bạn không?Kho lưu trữ và truy cập dữ liệu

Tôi có xu hướng nghĩ có nhưng tôi chỉ muốn xem suy nghĩ khác. Suy nghĩ của tôi là công việc của kho lưu trữ chỉ chứa và thực thi truy vấn thô, nơi mà lớp truy cập dữ liệu sẽ tạo ngữ cảnh, thực thi kho lưu trữ (đi trong ngữ cảnh), xử lý ánh xạ mô hình dữ liệu cho mô hình miền và trả lại kết quả sao lưu ...

Các bạn nghĩ sao? Ngoài ra bạn có thấy bất kỳ điều này thay đổi trong một kịch bản LINQ to XML (giả sử rằng bạn thay đổi ngữ cảnh cho XDocument có liên quan) không?

Cheers Anthony

UPDATE:

Đây là cách mà tôi sẽ thường thực hiện việc này trước:

public class TermBl : ITermBl 
{ 
    public IEnumerable<ITerm> GetAll(IListParameter criteria) 
    { 
     //Any pre business logic 

     var dataLayer = this.CreateDataLayer(); 
     var result = dataLayer.GetAll(criteria); 

     //Any post business logic 

     return result; 
    } 

    ... Other methods 
} 

public class TermDa : ITermDa 
{ 
    public IEnumerable<ITerm> GetAll(IListParameter criteria) 
    { 
     //Linq query 
     var dataResult = ....ToList() 

     var mappedResult = this.FromDataToDomain(dataResult); 
     //Note the mapping isn't done in this object, the actual 
     // mapping is handled by a separate component 

     return mappedResult; 
    } 

    ... Other methods 
} 

Bạn có thấy bất kỳ vấn đề cố hữu ở đây với các mô hình nói chung ..

Đối với kho lưu trữ nơi tôi đã nghĩ đến việc sử dụng nó thay vì truy vấn trực tiếp trong GetAll của TermDa Phương pháp tôi sẽ thay đổi nó để tìm một cái gì đó như thế này:

public class TermDa : ITermDa 
{ 
    public IEnumerable<ITerm> GetAll(IListParameter criteria) 
    { 
     var repository = this.CreateRepository(); 
     var dataResult = repository.GetAll(..., criteria).ToList(); 

     var mappedResult = this.FromDataToDomain(dataResult); 

     return mappedResult; 
    } 

    ... Other methods 
} 

public class TermRepository : ITermRepository 
{ 
    public IQueryable<ITerm> GetAll(IMyContext context, IListParameter criteria) 
    { 
     //Linq query 
     return ...; 
    } 

    ... Other queries 
} 

này như thế nào các bạn nhìn thấy nó làm việc hay không thực sự ... Có hay không có kho lưu trữ là tôi thấy một trong hai điều trên hoàn toàn bảo vệ các lớp kinh doanh từ biết bất kỳ điều gì về phương pháp/công nghệ truy cập dữ liệu được sử dụng ...

Trả lời

9

Có, có sự khác biệt lớn.

  • Một Dal (chẳng hạn như một Bảng liệu Gateway) là một cơ sở dữ liệu khái niệm. Nó có trách nhiệm phát hành các truy vấn tới cơ sở dữ liệu và trả về các tập bản ghi.

  • A kho lưu trữ là một khái niệm miền. Nó chịu trách nhiệm chấp nhận các yêu cầu có cấu trúc và trả về các đối tượng được đánh mạnh mẽ.

Rất khác nhau trong thực tế.


Cập nhật:

Câu hỏi đặt ra dường như để phản ánh một số lượng đáng kể của sự nhầm lẫn, vì vậy hãy để tôi cố gắng làm sáng tỏ với một ví dụ mã. Đây là một thiết kế mà bạn có thể sử dụng nếu bạn không sử dụng bất kỳ ORM nào và đang thực hiện tất cả ánh xạ của riêng bạn thay thế.Không ai trong số này là mã sản xuất chất lượng, nó chỉ cho mục đích giáo dục:

Data Access:

public interface IOrderData 
{ 
    IDataReader GetOrder(int orderID); 
} 

public interface IOrderDetailData 
{ 
    IDataReader GetOrderDetails(int orderID); 
} 

public interface IProductData 
{ 
    IDataReader GetProduct(int productID); 
} 

Tên miền:

public class Order 
{ 
    public int ID { get; set; } 
    public DateTime Date { get; set; } 
    public OrderStatus Status { get; set; } 
    // etc. 
    public IList<OrderDetail> Details { get; set; } 
} 

public class OrderDetail 
{ 
    public int ID { get; set; } 
    public Product Product { get; set; } 
    public int Quantity { get; set; } 
} 

Mapping:

public interface IDataMapper 
{ 
    Order MapOrder(IDataRecord record); 
    OrderDetail MapOrderDetail(IDataRecord record); 
    Product MapProduct(IDataRecord record); 
} 

Repository:

public interface IOrderRepository 
{ 
    Order GetOrder(int orderID); 
} 

public class OrderRepository 
{ 
    // These get initialized in the constructor 
    private readonly IOrderData orderData; 
    private readonly IOrderDetailData orderDetailData; 
    private readonly IProductData productData; 
    private readonly IDataMapper mapper; 

    public Order GetOrder(int orderID) 
    { 
     Order order; 
     using (IDataReader orderReader = orderData.GetOrder(orderID)) 
     { 
      if (!orderReader.Read()) 
       return null; 
      order = mapper.MapOrder(orderReader); 
     } 
     using (IDataReader detailReader = 
      orderDetailData.GetOrderDetails(orderID)) 
     { 
      while (detailReader.Read()) 
      { 
       OrderDetail detail = mapper.MapOrderDetail(detailReader); 
       detail.Product = ...; // Omitted for brevity, more reading/mapping 
       order.Details.Add(detail); 
      } 
     } 
     return order; 
    } 
} 

Đây có phải là làm cho ý nghĩa hơn bây giờ? DAL đang xử lý dữ liệu. Kho lưu trữ cụ thể có thể đóng gói các lớp truy cập dữ liệu nhưng kho lưu trữ trừu tượng (giao diện công cộng của nó) chỉ giao dịch với các lớp miền.

Một lần nữa tôi sẽ nhắc nhở người đọc rằng điều này thậm chí không gần với mã chất lượng sản xuất và hầu hết các ứng dụng hiện nay đều sử dụng ORM hoặc ít nhất một số bản đồ tự động tốt hơn. Điều này chỉ nhằm mục đích minh họa.

+0

Vì vậy, bạn có thấy đối tượng DAL sử dụng đối tượng kho lưu trữ không? tức là khi bạn nói phát hành truy vấn, tôi nghĩ rằng nó sẽ làm điều này bằng cách gọi kho lưu trữ ... gần giống như kho lưu trữ là proxy để lưu trữ procs trong cơ sở dữ liệu, ngoại trừ truy vấn trong kho ... –

+0

@vdh_ant: Không , một DAL thường không có bất kỳ kiến ​​thức nào về mô hình miền. Việc triển khai kho lưu trữ (không phải kiểu giao diện/cơ sở của nó) có thể sử dụng DAL, mặc dù hầu hết các dự án mới ngày nay thậm chí không có DAL, tất cả đều được đóng gói trong ORM.Kho lưu trữ là ** không ** proxy cho các đối tượng cơ sở dữ liệu, bạn đã hiểu nhầm nó là gì. – Aaronaught

+0

@Aaronaught: đặt kho lưu trữ một bên trong giây lát, khi bạn nói "DAL thường không có bất kỳ kiến ​​thức nào về mô hình miền", điều này đi ngược lại những gì tôi đã thấy xung quanh địa điểm ... suy nghĩ từ giao diện/giao diện hợp đồng DAL phải trả lại một cái gì đó và tôi chủ yếu thấy rằng một cái gì đó là mô hình miền. Khi tôi nghĩ về những gì khác nó có thể là nó chỉ có thể là các mô hình dữ liệu ... Tôi đã nghĩ rằng điều này là xấu vì nhiều lý do. Chủ yếu là vì lớp logic nghiệp vụ của bạn bây giờ được kết hợp với một mô hình dữ liệu cụ thể cho các công nghệ khác nhau ... –

1

Dường như bạn có khả năng xử lý tốt. "Lớp truy cập dữ liệu" có thể có nhiều hình dạng khác nhau. Đó là một số loại lớp học có liên quan đến truy cập dữ liệu. Kho lưu trữ của bạn là (A) một mẫu để xử lý sự kiên trì dữ liệu của bạn và (B) một vị trí trong lược đồ truy cập dữ liệu của bạn (nếu bạn đang triển khai kho lưu trữ).

Một thách thức trong chiến lược truy cập dữ liệu của bạn là cung cấp khả năng linh hoạt và khả năng tái sử dụng cùng một lúc. Đồng thời hiệu quả. Trong khi đồng thời làm việc với logic nghiệp vụ của bạn, được tách riêng nhưng cũng là cố kết. Khôn lanh.

Kho lưu trữ là mô hình nhằm mục đích trợ giúp tất cả số dư này. Mã của bạn để dịch db (hoặc bất kỳ) thành/từ các lớp thực thể nằm ở một nơi, cho mỗi thực thể. "Lớp truy cập dữ liệu" của bạn có thể bao gồm các lớp kho lưu trữ của bạn, cũng như các lớp thực sự xử lý công việc sql. Bạn chắc chắn không nên làm tất cả các tàu tuần dương sql trong mỗi lớp kho lưu trữ của bạn.

Ví dụ: bạn có thể bắt đầu bằng cách sử dụng phản chiếu không hiệu quả nhưng dễ dàng để điền vào các đối tượng thực thể của bạn, không làm việc trong các lớp kho của bạn; sau đó bạn có thể làm cho nó hiệu quả hơn đối với các thực thể có khối lượng lớn, nhưng điều này hoàn toàn bị ẩn khỏi các phần khác của hệ thống của bạn. Và sau đó bạn chuyển một số cấu hình sang XML, nhưng phần còn lại của hệ thống của bạn không có ý tưởng về thay đổi này.

Khuôn khổ LINQ-to-sql và Entity thực sự tận dụng mẫu lưu trữ, bởi vì những gì các lớp kho lưu trữ thực sự là một IQuerable của thực thể đó. Các lớp nghiệp vụ có thể áp dụng các tiêu chí bổ sung, và các tiêu chí đó thực sự làm cho nó trở thành sql, trong khi vẫn cung cấp sự đóng gói hoàn chỉnh từ sự kiên trì dữ liệu. Nó rất tuyệt.

+0

@Patrick Karcher: Vậy bạn có thấy đối tượng DAL sử dụng kho lưu trữ hay bạn thấy kho lưu trữ dưới dạng loại DAL khác hoặc không có chồng chéo ... nghĩa là bạn đã chọn sử dụng DAL hoặc kho lưu trữ từ lớp doanh nghiệp của mình ... –

+0

@vdh_ant Nếu bạn có một kho lưu trữ, bạn có thể nói đó là một nửa trong DAL của bạn và một nửa ở trên nó. Tốt hơn để nói nó * liên kết * DAL của bạn với tất cả mọi thứ ở trên đó. Hoặc, bạn có thể thấy nó như là kho lưu trữ của bạn * sử dụng * DAL (hoàn toàn ẩn khỏi tất cả giao diện người dùng và lớp kinh doanh của bạn) để duy trì dữ liệu của bạn. ** Hoặc **, bạn có thể có sqlconnections của bạn và như vậy ** trong ** các lớp kho lưu trữ của bạn. Nếu đây là trường hợp, bạn có thể trỏ vào các lớp kho lưu trữ của bạn và gọi chúng là DAL; có thể là "DAL +", vì nó không chỉ nhận/đặt dữ liệu của bạn mà còn kết thúc tốt đẹp đặc biệt cho phần còn lại của ứng dụng của bạn. ** DAL là một thuật ngữ mơ hồ! ** –

+0

@vdh_ant Những gì bạn đang cố gắng để có được một xử lý trên là (tôi nghĩ) phần khó khăn nhất của việc tạo ra một ứng dụng * linh hoạt * tốt. Nếu bạn đang bối rối về những gì chính xác mọi người có ý nghĩa của DAL, và làm thế nào để thiết lập tốt nhất "kết thúc trở lại" của ứng dụng của bạn, bạn đang ở trong công ty tốt! Những người rất thông minh, đã trả rất nhiều tiền, hiện tại đang nghĩ, "bây giờ, tôi làm cách nào để thiết lập truy cập dữ liệu cho dự án * this *." Bằng cách nhận ra bạn không biết cách tốt nhất, và hỏi những gì bạn đang hỏi, bạn đang đi trước rất nhiều người * tin * họ có tất cả những thứ này đã tìm ra. –

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