Linq查询中的调用类方法 [英] Call class method inside the Linq Query

查看:88
本文介绍了Linq查询中的调用类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个称为GetAge(DateTime birthDay)的方法.我想通过传递生日来在Linq查询中使用此方法,并基于返回的年龄值需要执行一些逻辑.

I have a method called GetAge(DateTime birthDay). I want to use this method in the Linq Query by passing the birthday and based on the returned age value need to perfrom some logic.

我想在下面以LINQ格式查询-

I want below query in LINQ format -

  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"

我们将非常感谢您的及时帮助.

Immediate help would be highly appreciated.

推荐答案

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的调用将检索到该点的查询结果,然后您将使用可以对其方法进行操作的本地对象.

The .AsEnumerable is required if you're attempting to query an SQL database as the GetAge method in your code will have no translation to SQL. In that case the call to .AsEnumerable retrieves the results of the query up to that point and you're then working with local objects on which your method can operate.

如果由于记录数太多而此时不想检索所有结果,则可以始终从要在查询中调用的方法中复制逻辑(我猜这里的逻辑) :

If you don't want to retrieve all the results at that point because the number of records is large you could always replicate the logic from the method you want to call in your query (I'm guessing at the logic 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);

由于所有操作都可以在SQL中使用,因此可以使用.

Because the operations are all available in SQL this will work.

如果要调用的方法特别复杂,则可以始终将其移至采用IQueryable并返回IQueryable的扩展方法.该方法的内容仍需要对SQL进行有效的翻译,但这将有助于隐藏更复杂的逻辑.

If the method you're trying to call is particularly complex you can always move it to an extension method that takes an IQueryable and returns an IQueryable. The contents of the method will still need to have a valid translation to SQL but it will help hide more complicated logic.

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

For example the above query could be made to look like this:

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

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

If the logic contained in your method doesn't translate to SQL for some reason though you have no choice but to convert the results set to LinqToObjects. In that case I'd suggest filtering the results as much as possible in SQL before calling AsEnumerable.

这篇关于Linq查询中的调用类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆