我想用自定义函数检查一些元素。
我有个人表:
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()函数。我有很多类似的功能。我想知道如何使用我的函数。
好吧,你不能。
如果希望在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);