context.Customer
.AsEnumerable() // because the method has no translation to SQL
.Where(customer => (GetAge(customer.BirthDate) > 20 && customer.AccountType == "Savings")
|| (GetAge(customer.BirthDate) > 40 && customer.AccountType == "Current"));
Il .AsEnumerable
è necessario se si sta tentando di interrogare un database SQL come metodo GetAge nel codice non avrà traduzione in SQL. In tal caso, la chiamata a .AsEnumerable
recupera i risultati della query fino a quel punto e quindi si lavora con gli oggetti locali su cui il metodo può operare.
Se non si desidera recuperare tutti i risultati a quel punto perché il numero di record è elevato, è sempre possibile replicare la logica dal metodo che si desidera chiamare nella query (Sto indovinando la logica qui):
Poiché le operazioni sono tutte disponibili in SQL, funzionerà.
Se il metodo che si sta tentando di chiamare è particolarmente complesso, è sempre possibile spostarlo su un metodo di estensione che prende uno IQueryable
e restituisce un IQueryable
. Il contenuto del metodo dovrà comunque avere una traduzione valida in SQL ma aiuterà a nascondere una logica più complicata.
Ad esempio, la query di cui sopra potrebbe essere fatto per assomigliare a questo:
context.Customers.WhoAreValidByAge();
Dove WhoAreValidByAge
è definito come:
public static IQueryable<Customer> WhoAreValidByAge(this IQueryable<Customer> customers)
{
cusomters.Select(c => new { Customer = c, Age = (DateTime.Today.Year - c.BirthDate.Year) }
.Where(c => (c.Age > 20 && c.Customer.AccountType == "Savings")
|| (c.Age > 40 && c.Customer.AccountType == "Current"))
.Select(c => c.Customer)
}
Se la logica contenuta nel metodo non si traduce a SQL per qualche motivo sebbene non abbia altra scelta che convertire i risultati impostati in LinqToObjects. In tal caso, suggerirei di filtrare i risultati il più possibile in SQL prima di chiamare AsEnumerable
.
fonte
2010-11-03 09:33:46
È questo LINQ to SQL? – Ani
Questo è Linq alle entità. Sto usando Entity Framework. –