инкапсуляция логики в запросе linq to sql через метод расширения

Даны два класса в вашем файле LINQ to SQL .dbml со следующими свойствами.

Customer
    CustomerId
    FirstName
    LastName
    AddressId

Address
    AddressId
    Street
    City
    State
    Zip

Вы можете создать запрос LINQ, например, следующий.

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

}

Теперь допустим, вы хотели объяснить логику составления почтового адреса. Это можно сделать двумя способами: добавить новое свойство к классу Customer или создать метод расширения.

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

Теперь вы можете использовать один из них, и вы получите правильные результаты.

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

}

Проблема с обоими способами заключается в том, что это приведет к дополнительному обходу базы данных для каждой строки, которую вы извлекаете. Первоначальный запрос извлечет информацию из таблицы Customer, а затем ему нужно будет оценить каждую запись адреса индивидуально, когда она будет оценивать почтовый адрес.

Есть ли способ инкапсулировать эту логику и связать ее с классом клиентов таким образом, что вам не нужны дополнительные обращения к базе данных?

Я думаю, что должен быть какой-то способ создать метод расширения, который вместо строки возвращает выражение. Я прав? Если так, как мне это сделать?

5
задан eoldre 14 October 2010 в 16:11
поделиться