2009-02-06 37 views
18

Tôi đang bắt đầu một dự án mới và đã quyết định thử kết hợp các mẫu DDD và cũng bao gồm LINQ to Entities. Khi tôi nhìn vào ObjectContext của EF, nó dường như đang thực hiện các chức năng của cả hai mẫu Repository và Unit of Work:Khung thực thể là Kho lưu trữ và UnitOfWork?

Kho lưu trữ theo nghĩa là giao diện mức dữ liệu cơ bản được trừu tượng hóa từ biểu diễn thực thể và tôi có thể yêu cầu và lưu dữ liệu thông qua ObjectContext.

Unit Of Work theo nghĩa là tôi có thể viết tất cả các chèn/cập nhật của mình vào đối tượngContext và thực hiện tất cả trong một lần khi tôi thực hiện SaveChanges().

Có vẻ như dư thừa để đặt một lớp khác của các mẫu này lên trên đối tượng EFContext? Dường như các lớp Model có thể được kết hợp trực tiếp trên các thực thể được tạo bởi EF bằng cách sử dụng 'partial class'.

Tôi mới tại DDD vì vậy hãy cho tôi biết nếu tôi là thiếu một cái gì đó ở đây.

Trả lời

17

Tôi không nghĩ rằng khung Entity là một việc thực hiện tốt các Repository, bởi vì:

  • Bối cảnh đối tượng là không đủ trừu tượng để làm kiểm tra đơn vị tốt điều đó tham chiếu đến nó, vì nó là ràng buộc để quyền truy cập DB. Có một tài liệu tham khảo IRepository thay vì hoạt động tốt hơn cho việc tạo ra các bài kiểm tra đơn vị.
  • Khi khách hàng có quyền truy cập vào ObjectContext, khách hàng có thể thực hiện khá nhiều thứ mà họ quan tâm. Điều khiển thực sự duy nhất mà bạn có trên điều này là làm cho một số loại hoặc thuộc tính riêng tư. Thật khó để thực hiện bảo mật dữ liệu tốt theo cách này.
  • Trên mô hình không tầm thường, ObjectContext không đủ trừu tượng. Ví dụ, bạn có thể có cả hai bảng và các thủ tục lưu sẵn được ánh xạ tới cùng một loại thực thể. Bạn không thực sự muốn khách hàng phải phân biệt giữa hai ánh xạ.
  • Trên một lưu ý liên quan, rất khó để viết các quy tắc kinh doanh toàn diện và nổi thực thi và mã đơn vị. Thật vậy, có hay không điều này thậm chí là một ý tưởng tốt là gây tranh cãi.

Mặt khác,, khi bạn có ObjectContext, việc triển khai mẫu Kho lưu trữ là không đáng kể. Thật vậy, đối với các trường hợp không đặc biệt phức tạp, Kho lưu trữ là thứ gì đó của trình bao bọc xung quanh ObjectContext và các loại Thực thể.

+2

Cảm ơn Craig. Tôi đã xem qua một số mã trong blog của Simon Segal tại http://www.simonsegal.net/blog/2009/01/13/entity-framework-repository-specifications-and-fetching-strategies/ cung cấp một số triển khai Kho mẫu cho khung thực thể. – Weej

+0

Bạn hiện đang sử dụng EntityFramework trong thiết kế của mình chưa? Có khó khăn gì trong việc triển khai không? Cảm ơn bạn lần nữa – Weej

+0

Vâng, chúng tôi đang sử dụng Khung thực thể. Không có khó khăn gì cả khi triển khai Repository xung quanh; là tầm thường. Chúng ta có tất cả các loại khó khăn với chính Khuôn khổ thực thể; Tôi nghĩ rằng điều này có lẽ đúng với bất kỳ ORM nào. –

7

Tôi sẽ nói rằng bạn nên xem ObjectContext là UnitOfWork của bạn và không phải là kho lưu trữ.

Một ObjectContext không thể là một kho lưu trữ -imho- vì nó là 'chung chung'. Bạn nên tạo các kho lưu trữ của riêng bạn, có các phương thức chuyên biệt (ví dụ như GetCustomersWithGoldStatus) bên cạnh các phương thức CRUD thông thường.

Vì vậy, những gì tôi sẽ làm, là tạo kho (một cho mỗi tập hợp gốc), và để cho các kho lưu trữ đó sử dụng ObjectContext.

+0

Cảm ơn các bình luận Frederik. Bạn có triển khai GetCustomersWithGoldStatus trực tiếp trong kho lưu trữ không? Bạn đã cân nhắc sử dụng các phương pháp Mở rộng chưa? Bạn có nghĩ rằng các phương pháp mở rộng có một vị trí trong kịch bản này? – Weej

+0

Bạn sẽ tạo loại phương thức mở rộng nào trên loại đó? Tôi thực sự sẽ tạo nó trên kho lưu trữ, nhưng không phải là một phương pháp mở rộng. Kho lưu trữ có thể được coi là 'bộ sưu tập', nơi bạn có được các thực thể, vì vậy tôi nghĩ rằng đó là một nơi hợp lệ để làm điều đó theo cách này –

0

Tôi muốn có một lớp kho vì những lý do sau đây:

EF Gotcha của

Khi bạn nhìn vào một số các hướng dẫn hiện hành về EF (Mã đầu tiên phiên bản), người ta rõ ràng có một số lượng của gotcha được xử lý, đặc biệt là xung quanh các đồ thị đối tượng (các thực thể chứa các thực thể) và các tình huống bị ngắt kết nối. Tôi nghĩ rằng một tầng kho lưu trữ là rất tốt cho gói này lên ở một nơi.

Một bức tranh rõ ràng về cơ chế truy cập dữ liệu

Một kho đưa ra một hình ảnh cụ thể như thế nào BL đang truy cập và cập nhật kho dữ liệu. Nó cho thấy các phương pháp có một mục đích rõ ràng, và có thể được kiểm tra độc lập với BL. Ví dụ tiêu chuẩn từ sách giáo khoa, Tìm() để tìm một thực thể. Một ví dụ cụ thể về ứng dụng hơn, Xóa() để xóa bảng db.

Một nơi cho việc tối ưu

Chắc chắn bạn đi lên chống lại hit hiệu suất khi sử dụng vani EF. Tôi sử dụng kho lưu trữ để ẩn các cơ chế tối ưu hóa từ BL.

Ví dụ,

GetKeys() để dự phím cache từ các bảng (đối với các quyết định/Cập nhật Insert). Việc đọc khóa chỉ nhanh hơn và sử dụng ít bộ nhớ hơn là đọc thực thể đầy đủ.

Tải hàng loạt qua SqlBulkCopy. EF sẽ chèn bằng các câu lệnh SQL riêng lẻ. Nếu bạn muốn có một câu lệnh đơn để chèn nhiều hàng, SqlBulkCopy là một cơ chế tốt. Kho lưu trữ đóng gói này và cung cấp siêu dữ liệu cho SqlBulkCopy. Cũng như phương thức Insert, bạn cần một phương thức StartBatch() và EndBatch(), cũng là một đối số cho một lớp UnitOfWork.

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