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"));
.AsEnumerable is required if you are trying to query an SQL database because the GetAge method in your code will not be translated into SQL. In this case, calling .AsEnumerable returns the query results to this point, and you then work with local objects that your method can work on.
If you do not want to get all the results at this point, because the number of records is large, you can always replicate the logic from the method you want to call in your request (I assume that the logic is here)
context.Customer.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);
Since all operations are available in SQL, this will work.
If the method you are trying to call is particularly complex, you can always port it to an extension method that accepts IQueryable and returns IQueryable . The contents of the method should still have a valid SQL translation, but this will help to hide more complex logic.
For example, the above query might look like this:
context.Customers.WhoAreValidByAge();
Where WhoAreValidByAge is defined as:
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) }
If the logic contained in your method doesnβt translate into SQL for some reason, although you have no choice but to convert the results set to LinqToObjects. In this case, I suggest filtering the results as much as possible in SQL before calling AsEnumerable .
Dave downs
source share