IQueryable中的自定义方法<;T>;.选择

本文关键字:gt 选择 lt 自定义方法 IQueryable | 更新日期: 2023-09-27 18:24:05

我需要在IQueryable<T>.Select语句中运行自定义方法,例如

query.Select(r => new ResultObject()
{
Id = r.Persion.Id,
Code = r.Person.Code,
CalculatedField = CalculateField(r.Person)
}

问题是,我不能这样运行它,因为linq-to-sql异常被抛出。CalculateField基本上是一个switch语句:

private static CalcFieldEnum CalculateField(Person p)
{
    if(p.Age < 21)
    {
         if(p.Salary > 2000 && p.YearsWorked > 2)
             return CalcFieldEnum.TypeB;
         else if(p.YearsWorked <= 2)
             return CalcFieldEnum.TypeC;
    }
    else
    {
        if(p.Salary > 3000)
            return CalcFieldEnum.TypeB;
    }
    return CalcFieldEnum.TypeA;
}

该方法(CalculateField)唯一重要的一点是,它只接受一些实体,并根据实体的字段值返回结果。

我不能在查询后运行这个方法,因为用户可以按列对结果进行排序,排序也可以在IQueryable上运行。有什么办法可以解决这个问题吗?

p.S我简化了方法的逻辑,实际上有很多的if-else语句。不过,这个想法是一样的——它只是根据对象的字段返回一个枚举值。

IQueryable中的自定义方法<;T>;.选择

如果可以将方法重写为lambda,例如

p => p.Age < 21
    ? (
        (p.Salary > 2000 && p.YearsWorked > 2)
            ? CalcFieldEnum.TypeB
            : (p.YearsWorked <= 2 ? CalcFieldEnum.TypeC : CalcFieldEnum.TypeA)
      )
    : ( p.Salary > 3000 ? CalcFieldEnum.TypeB : CalcFieldEnum.TypeA);

那么您应该能够将它传递到数据库。

您想要做的是不受支持的,老实说,不可能将每个自定义C#方法转换为SQL语句。看看:

使用我自己的LINQ to Entities 方法

http://forums.asp.net/t/1858815.aspx?LINQ+to+Entities+does+not+identify+the+method+exception+when+using+custom+extension+method

您可以使用AsEnumerable方法从数据库中提取和加载记录,然后使用您想要的任何方法:

query.AsEnumerable().Select(...);