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

时间:2013-02-05 10:38:06

标签: c# asp.net-mvc linq filter

我想通过使用自定义函数检查它们来获取一些元素。

我有人员表:

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()函数。我有很多这样的功能。我想知道如何使用我的功能。

5 个答案:

答案 0 :(得分:3)

嗯,你做不到。

如果要在SQL查询的Where子句中使用标准,则需要将它们直接写为linq.Expression,以便实体可以解析它并将其转换为SQL,而不是外部函数。

这样的事情有效:

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

答案 1 :(得分:0)

Query Expressions内置于C#编译器中,因此,它只能理解编译器内置的表达式。

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

为什么不使用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;
}

答案 4 :(得分:0)

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

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

这样的事情:

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