2008-09-09 32 views
11

Gần đây tôi đã bắt đầu dự án biểu mẫu web mới và quyết định tách riêng các lớp kinh doanh khỏi bất kỳ tham chiếu DBML nào. Lớp lớp kinh doanh của tôi thay vì truy cập các phương thức lớp dữ liệu rời rạc và được trả về các bộ sưu tập của DTO. Vì vậy, các lớp dữ liệu có thể dự DTO của như sau:Tách mối quan tâm với LINQ To SQL và DTO's

(from c in dataContext.Customers 
where c.Active == true 
select new DTO.Customer 
{ 
    CustomerID = c.CustomerID, 
    Name = c.CustomerName, 
    ... 
}).ToList() 

Mặc dù việc xây dựng các đối tượng DTO thêm công việc, điều này cảm thấy như một cách tiếp cận tốt hơn để một chặt chẽ ràng buộc giữa kinh doanh & lớp dữ liệu và có nghĩa là tôi có thể kiểm tra các lớp kinh doanh mà không cần một cơ sở dữ liệu đang có mặt.

Câu hỏi của tôi là thực hành tốt này ?, Có cách nào tạo ra DTO (có thể thông qua SQLMetal) hay không và tôi có thể tấn công những vấn đề nào khác khi dự án diễn ra.

+0

Tôi đã đăng một số liên kết về ánh xạ XML bên ngoài tại đây: http://stackoverflow.com/questions/988872/linq-to-sql-external-mapping/1136039#1136039 – alexandrul

Trả lời

5

Tôi không biết thực hành tốt nhất nhưng tôi đã viết mã tương tự trong quá khứ không quá gần đây vì tôi cũng cảm thấy rằng tôi có thể cải thiện việc phân tách mối quan tâm bằng cách sử dụng các lớp của riêng tôi thay vì tạo LINQ-designer những cái trong ứng dụng của tôi.

Bạn có thể muốn xem xét việc chỉ trả lại một IQueryable <Customer> thay vì một IList <Customer> từ phương thức truy cập dữ liệu của bạn. Kể từ IQueryable <T> thừa hưởng từ IEnumerable <T> phần còn lại của ứng dụng của bạn sẽ có thể đối phó với nó khá tốt. Bạn cũng có thể chuyển đổi nó thành Danh sách khi bạn thực sự cần.

Lợi thế của việc này là bạn có thể tự động sửa đổi truy vấn của mình khá dễ dàng và giảm thiểu lượng dữ liệu được trả về từ SQL Server.

Ví dụ: nếu chữ ký phương thức của bạn là IQueryable < Khách hàng > GetCustomers() bạn có thể có được một khách hàng bằng cách gọi cho GetCustomers() ở đâu (c => c.CustomerID == 101) .Single();

Trong ví dụ này, chỉ một bản ghi sẽ được trả về từ cơ sở dữ liệu trong khi tôi cho rằng mã của bạn sẽ trả về tất cả các khách hàng hoặc bạn phải viết các phương thức riêng biệt (và mã rất lặp lại) để phục vụ cho tất cả những thứ bạn có thể muốn lọc theo.

+4

Tôi khuyên bạn nên đối diện chính xác. Tôi sẽ không bao giờ trả lại một IQuerable qua một IList bên ngoài DAL. Nếu bạn làm như vậy, thì lớp trình bày của bạn có khả năng sẽ kết thúc thực hiện các truy vấn cơ sở dữ liệu một cách vô ý, hoặc bạn có thể kết thúc việc trộn các cuộc gọi LINQ-to-objects và nhận lỗi Linq-to-sql. Trả lại IQuerable từ Linq-to-sql làm cho một kiến ​​trúc thực sự kém và bị rò rỉ và nên tránh cho tất cả trừ các ứng dụng đồ chơi dinkiest. – mattmc3

2

Theo tôi trong nhiều trường hợp đối tượng DTO không cần thiết khi giao dịch với LINQ. Các lớp LINQ được tạo có thể dễ dàng được kiểm tra. LINQ cung cấp cho bạn khả năng truy vấn dữ liệu của bạn từ các nguồn khác nhau bằng cách sử dụng các truy vấn giống hệt nhau. Nó cung cấp cho bạn khả năng kiểm tra các truy vấn của bạn dựa vào danh sách các đối tượng thay vì db thực.

+0

Đồng ý. Về bản chất, các đối tượng LINQ-to-sql của bạn có thể được coi là các DTO, và thậm chí có cả một mẫu T4 để tạo các đối tượng L2S ​​của bạn như serializable. – mattmc3