【问题标题】:How use my own function in Linq query?如何在 Linq 查询中使用我自己的函数?
【发布时间】:2013-01-20 06:15:19
【问题描述】:

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

我有 Person 表:

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

【问题讨论】:

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


    【解决方案1】:

    嗯,你不能。

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

    这样的工作:

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

    【讨论】:

    • 所以,我不能使用我的功能。是的?因为,我还有一些其他函数可以过滤 Persons,而不仅仅是 GetAge()。感谢您的帮助。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      或者你可以使用这个语法:

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

      【讨论】:

        【解决方案4】:

        为什么不使用List&lt;Person&gt;.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;
        }
        

        【讨论】:

          【解决方案5】:

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

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

          类似这样的:

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

          【讨论】:

            猜你喜欢
            • 2016-06-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多