Dadas dos clases en su archivo .dbml LINQ to SQL con las siguientes propiedades.encapsulando la lógica en una consulta de linq a sql a través del método de extensión
Customer
CustomerId
FirstName
LastName
AddressId
Address
AddressId
Street
City
State
Zip
Puede construir una consulta LINQ como la siguiente.
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();
}
Ahora digamos que quería excapsular la lógica para armar la dirección postal. Dos formas de lograr eso serían agregar una nueva propiedad a la clase Cliente o crear un método de extensión.
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;
}
}
}
ahora se podían usar uno de esos y se podrían obtener los resultados correctos
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();
}
El problema con estas dos formas es que al hacerlo provocará que haya un ida y vuelta innecesaria a la base de datos para cada fila que recupera. La consulta inicial extraerá la información de la tabla Cliente, y luego tendrá que graduar cada registro de dirección individualmente cuando evalúe la dirección postal.
¿Hay alguna manera de encapsular esta lógica y vincularla a la clase de los clientes de tal forma que no necesite ningún viaje adicional de ida y vuelta a la base de datos?
Creo que debe haber alguna manera de crear un método de extensión que en su lugar devuelva una expresión en lugar de una cadena. ¿Estoy en lo cierto? Si es así, ¿cómo haría esto?
Gracias Richard, eso funciona, pero tienes razón, no es exactamente lo que espero encontrar por dos razones. Primero, el método de llamada necesita saber algo sobre lo que está involucrado en la construcción de 'MailingAddress', es decir, que requiere la tabla de direcciones. En segundo lugar, digamos que la tabla de direcciones en realidad contenía muchos más de 5 campos, creo que hacer esto generaría muchos más datos de los que realmente necesitamos. – eoldre