在Linq Query中调用类方法

我有一个名为GetAge(DateTime birthDay)的方法。 我想在Linq Query中使用这个方法,通过传递生日并根据返回的年龄值需要执行一些逻辑。

我想在LINQ格式下面查询 –

from customer in contetx.Customer where if GetAge(customer.BirthDate) > 20 and customer.accountType="Savings" or if(GetAge(customer.BirthDate) > 40 and customer.AccountType="Current" 

立即的帮助将受到高度赞赏。

 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")); 

如果您尝试查询SQL数据库,则需要.AsEnumerable,因为代码中的GetAge方法无法转换为SQL。 在这种情况下,对.AsEnumerable的调用会检索到该点的查询结果,然后您将使用您的方法可以在其上运行的本地对象。

如果您不想在那时检索所有结果,因为记录数量很大,您总是可以从要在查询中调用的方法复制逻辑(我在这里猜测逻辑):

 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); 

因为这些操作都在SQL中可用,所以这将起作用。

如果您尝试调用的方法特别复杂,则可以始终将其移动到采用IQueryable并返回IQueryable的扩展方法。 该方法的内容仍然需要有一个有效的SQL转换,但它将有助于隐藏更复杂的逻辑。

例如,上面的查询可以看起来像这样:

 context.Customers.WhoAreValidByAge(); 

WhoAreValidByAge定义为:

 public static IQueryable WhoAreValidByAge(this IQueryable 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) } 

如果您的方法中包含的逻辑由于某种原因没有转换为SQL,尽管您别无选择,只能将结果集转换为LinqToObjects。 在这种情况下,我建议在调用AsEnumerable之前尽可能在SQL中过滤结果。

 var customers = from customer in contetx.Customer let age = GetAge(customer.BirthDate) where (age > 20 && customer.accountType == "Savings") || (age > 40 && customer.accountType == "Current") select customer; 

你可以这样做:

 var query = from customer in contetx.Customer where (GetAge(customer.BirthDate) > 20 && customer.AccountType == "Saving") || (GetAge(customer.BirthDate) > 40 && customer.AccountType == "Current") select customer; 

你可以像Darin一样使用let关键字来调用GetAge两次。

 var query from customer in // ... let age = GetAge(customer.BirthDate) where // ... select customer;