2010-10-14 32 views
5

Cho hai lớp trong tệp LINQ to SQL .dbml của bạn với các phần sau thích hợp.logic đóng gói trong truy vấn LINQ đến sql thông qua phương thức mở rộng

Customer 
    CustomerId 
    FirstName 
    LastName 
    AddressId 

Address 
    AddressId 
    Street 
    City 
    State 
    Zip 

Bạn có thể tạo truy vấn LINQ như sau.

using(var db = new MyDataContext()) 
{ 
    results = db.Customers 
     .Where(c => c.LastName.BeginsWith("o")) 
     .Select(c => new 
      { 
       c.CustomerId, 
       MailingAddress = c.FirstName + " " 
        + c.LastName 
        + Environment.NewLine 
        + c.Address.Street 
        + Environment.NewLine 
        + c.Address.City + ", " 
        + c.Address.State + " " 
        + c.Address.Zip 
      }).ToList(); 

} 

Bây giờ, giả sử bạn muốn đóng gói logic để đặt cùng địa chỉ gửi thư. Hai cách mà bạn có thể thực hiện đó là thêm thuộc tính mới vào lớp Customer hoặc tạo một phương thức mở rộng.

public static class CustomerExtensions 
{ 
    public static string GetMailingAddress(this Customer cust) 
    { 
     return cust.FirstName + " " 
        + cust.LastName 
        + Environment.NewLine 
        + cust.Address.Street 
        + Environment.NewLine 
        + cust.Address.City + ", " 
        + cust.Address.State + " " 
        + cust.Address.Zip; 
    } 
} 

public partial class Customer 
{ 
    public string MailingAddress 
    { 
     get 
     { 
      return this.FirstName + " " 
        + this.LastName 
        + Environment.NewLine 
        + this.Address.Street 
        + Environment.NewLine 
        + this.Address.City + ", " 
        + this.Address.State + " " 
        + this.Address.Zip; 
     } 
    } 
} 

bây giờ bạn có thể sử dụng một trong những người và bạn sẽ nhận được kết quả chính xác

using(var db = new MyDataContext()) 
{ 
    results = db.Customers 
     .Where(c => c.LastName.BeginsWith("o")) 
     .Select(c => new 
      { 
       c.CustomerId, 
       c.MailingAddress, //new property 
       Address2 = c.GetMailingAddress() // new extension method 
      }).ToList(); 

} 

Vấn đề với cả hai cách được rằng làm như vậy sẽ gây ra có được một chuyến đi vòng bổ sung cho các cơ sở dữ liệu cho mỗi hàng bạn truy xuất. Truy vấn ban đầu sẽ lấy lại thông tin từ bảng Khách hàng, và sau đó nó sẽ cần phải phân loại từng bản ghi địa chỉ riêng lẻ khi nó đánh giá địa chỉ gửi thư.

Có cách nào để gói gọn logic này và buộc nó vào lớp khách hàng theo cách mà bạn không cần thêm bất kỳ chuyến đi vòng nào vào cơ sở dữ liệu không?

Tôi nghĩ rằng phải có một số cách để tạo phương thức mở rộng thay vì trả về một biểu thức thay vì một chuỗi. Tôi có đúng không? Nếu vậy, làm thế nào tôi sẽ làm điều này?

Trả lời

3

Tôi biết điều này không phải là chính xác những gì bạn đang tìm kiếm, nhưng bạn có thể làm điều này:

var options = new DataLoadOptions(); 
options.LoadWith<Customer>(c => c.Address); 
db.LoadOptions = options; 

Sau đó, nó sẽ chỉ làm cho một chuyến đi như địa chỉ được lấy ra với khách hàng.

+0

Cảm ơn Richard, điều đó có hiệu quả nhưng bạn nói đúng, đó không phải là điều tôi hy vọng tìm được vì hai lý do. Đầu tiên, phương thức gọi điện sau đó cần phải biết điều gì đó liên quan đến việc xây dựng 'MailingAddress', nghĩa là nó yêu cầu bảng địa chỉ. Thứ hai, cho phép nói rằng bảng địa chỉ thực sự chứa nhiều hơn 5 trường, tôi tin rằng làm điều này sẽ mang lại nhiều dữ liệu hơn chúng ta thực sự cần. – eoldre

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