Dato due classi nel file LINQ to SQL .dbml con le seguenti proprietà.logica di incapsulamento in una query da linq a sql tramite il metodo di estensione
Customer
CustomerId
FirstName
LastName
AddressId
Address
AddressId
Street
City
State
Zip
È possibile creare una query LINQ come la seguente.
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();
}
Ora diciamo che si desiderava escludere la logica per mettere insieme l'indirizzo postale. Due modi che potresti ottenere sarebbe aggiungere una nuova proprietà alla classe Customer o creare un metodo di estensione.
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;
}
}
}
si potrebbe ora usare uno di questi e si dovrebbe ottenere i risultati corretti
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();
}
Il problema con entrambi questi modi è che così facendo farà sì che ci sia un viaggio in più intorno al database per ogni riga che si recupera. La query iniziale estrarrà le informazioni dalla tabella Customer e quindi dovrà valutare ogni record dell'indirizzo singolarmente quando valuta l'indirizzo postale.
C'è un modo per incapsulare questa logica e legarla alla classe cliente in modo tale da non aver bisogno di ulteriori viaggi di andata e ritorno nel database?
Penso che ci sia un modo per creare un metodo di estensione che restituisca invece un'espressione invece di una stringa. Ho ragione? Se sì, come lo farei?
Grazie Richard, funziona ma hai ragione, non è proprio quello che spero di trovare per due motivi. In primo luogo, il metodo di chiamata deve quindi sapere qualcosa su ciò che è coinvolto nella costruzione di "MailingAddress", cioè che richiede la tabella degli indirizzi. In secondo luogo, diciamo che la tabella degli indirizzi conteneva in realtà molti più di 5 campi, credo che fare ciò porterebbe indietro molti più dati di quanti ne abbiamo effettivamente bisogno. – eoldre