Даны два класса в вашем файле 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, а затем ему нужно будет оценить каждую запись адреса индивидуально, когда она будет оценивать почтовый адрес.
Есть ли способ инкапсулировать эту логику и связать ее с классом клиентов таким образом, что вам не нужны дополнительные обращения к базе данных?
Я думаю, что должен быть какой-то способ создать метод расширения, который вместо строки возвращает выражение. Я прав? Если так, как мне это сделать?