2010-10-14 13 views
5

LINQ to SQL .dbml dosyanızdaki aşağıdaki sınıflara sahip iki sınıf verildi.mantıkta bir mantıkta sql sorguyu uzantı yöntemiyle kapsülleme

Customer 
    CustomerId 
    FirstName 
    LastName 
    AddressId 

Address 
    AddressId 
    Street 
    City 
    State 
    Zip 

Aşağıdaki gibi bir LINQ sorgusu oluşturabilirsiniz.

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(); 

} 

Şimdi, posta adresini bir araya getirme mantığını dışarıda bırakmak istediğinizi varsayalım. Bunu gerçekleştirebilmenin iki yolu, Müşteri sınıfına yeni bir özellik eklemek veya bir uzantı yöntemi oluşturmaktır.

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; 
     } 
    } 
} 

şimdi onlardan biri kullanabilir ve doğru sonuçlar

alacağı
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(); 

} 

Bunu yaparken ekstra gidiş-dönüş olacaksa neden olacaktır ki bu yollardan ikisi ile sorun Aldığınız her satır için veritabanı. İlk sorgu, Müşteri tablosundan bilgileri geri çekecek ve daha sonra posta adresi için değerlendirildiğinde her adres kaydını ayrı ayrı tutması gerekecektir.

Bu mantığı kapsüllemek ve veritabanına fazladan gidiş dönüş yapmanıza gerek kalmayacak şekilde müşteri sınıfına bağlamak için bir yol var mı?

Bunun yerine bir dize yerine bir ifade döndüren bir uzantı yöntemi oluşturmanın bir yolu olması gerektiğini düşünüyorum. Ben haklı mıyım Eğer öyleyse, bunu nasıl yapardım?

cevap

3

Ben bu tam aradığınız ne değildir biliyorum, ama bunu yapabilirsiniz: Adres Müşteri ile alınır olarak

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

Sonra tek yolculuk yapacak.

+0

Teşekkürler Richard, bu işe yarıyor ama haklısınız, iki nedenden dolayı bulmayı umduğum şey tam olarak değil. Birincisi, çağrı yönteminin daha sonra, 'MailingAddress' in oluşturulması ile ilgili olan, yani adres tablosunu gerektiren şey hakkında bir şey bilmesi gerekir. İkincisi, adres tablosunun aslında 5'ten fazla alan içerdiğini söyleyeyim, bunu yapmanın aslında ihtiyacımız olandan çok daha fazla veri getireceğine inanıyorum. – eoldre