我有一个名为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"
立即提供帮助将受到高度赞赏。
答案 0 :(得分:11)
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;
答案 1 :(得分:7)
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<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)
}
如果您的方法中包含的逻辑由于某种原因没有转换为SQL,尽管您别无选择,只能将结果集转换为LinqToObjects。在这种情况下,我建议在调用AsEnumerable
之前尽可能在SQL中过滤结果。
答案 2 :(得分:0)
你可以这样做:
var query = from customer in contetx.Customer
where (GetAge(customer.BirthDate) > 20 && customer.AccountType == "Saving") ||
(GetAge(customer.BirthDate) > 40 && customer.AccountType == "Current")
select customer;
使用GetAge
关键字作为Darin,你可以绕过两次调用let
。
var query from customer in // ...
let age = GetAge(customer.BirthDate)
where // ...
select customer;