在Linq Query中调用类方法

时间:2010-11-03 09:29:01

标签: c# linq

我有一个名为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"

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

3 个答案:

答案 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;