如何在Linq查询中使用我自己的函数

本文关键字:我自己 自己的 函数 Linq 查询 | 更新日期: 2023-09-27 17:57:47

我想用自定义函数检查一些元素。

我有个人表:

public class Person
{
        public int Id { get; set; }
        public DateTime BirthDay { get; set; }
        public string Name { get; set; }
        ...
}

我应该使用我的GetAge()和其他函数来过滤人员列表。我的以下代码不起作用:

public List<Person> FilterPersons(int ageFrom, int ageTo...etc..) 
{
    var all = Database.Persons.AsQueryable(); 
    all = from item in all
          where GetAge(item.BirthDay) > ageFrom
          select item;
    all = from item in all
          where GetAge(item.BirthDay) < ageTo
          select item;
    // other operations
    ...
}

我想我可以这样写。在每一步做到这一点:

List<Person> newList = new List<Person>();
foreach (var item in all)
{
   var itemAge = Common.GetAge(item.BirthDay);
   if (itemAge > AgeFrom)
   {
       newList.Add(item);
   }
}
all = newList.List();

但这并不是我认为的最好的方式,因为我应该通过许多生物来过滤。它将以低速工作。

如何在Linq查询中使用我的函数?

编辑:例如,我展示了GetAge()函数。我有很多类似的功能。我想知道如何使用我的函数。

如何在Linq查询中使用我自己的函数

好吧,你不能。

如果希望在SQL查询的Where子句中使用条件,则需要将它们直接写成linq。表达式,以便实体可以解析它并将其转换为SQL,而不是外部函数。

像这样的东西有效:

DateTime date = DateTime.Now.AddDays(ageFrom);
all = from item in all
      where item.BirthDay > date
      select item;

查询表达式是C#编译器内置的,因此,它只理解编译器内置的表达式。

例如,当您使用where关键字时,它会将其转换为对Where<TSource>(this IQueryable<TSource> source, Func<TSource, bool> predicate)方法的调用。

Linq-To对象和Linq-To SQL都是如此。更重要的是,使用Linq-To-SQL,编译器必须将查询表达式转换为SQL,这无法知道GetAge方法的定义。

或者您可以使用以下语法:

DateTime date = DateTime.Now.AddDays(ageFrom);
all = item.Where(x => x.BirthDay > date).ToList();

为什么不使用List<Person>.FindAll()方法并传入方法筛选器作为谓词?你会用这样的方法。

List<Person> filteredPersons = allPersons.FindAll(FilterPersons);

以下是您将用作过滤器的示例方法。

bool FilterPersons(Person p)
{
    if(//enter criteria here to determine if you want to select the person)
        return true;
    else
        return false;
}

要做你想做的事情,这可能是你需要的代码。

bool FilterPersons(Person p)
{
    var itemAge = Common.GetAge(item.BirthDay);
    if( itemAge > AgeFrom )
        return true;
    else
        return false;
}

假设您可以对结果应用过滤器:

可以应用普通过滤器(在linq表达式中),然后对结果应用函数。当然,您需要refactor您的方法。

类似这样的东西:

var result= Users.Where(s=>s.Name).ToList();
result= MyFilter(result);