【问题标题】:Manipulating variable type within LINQ expression在 LINQ 表达式中操作变量类型
【发布时间】:2014-05-15 15:39:03
【问题描述】:

我正在尝试返回符合我选择的年龄过滤器的年龄视图。我读到 LINQ 不能执行实际的 C# 操作,例如 .ToString() 或 int.Parse,因此您必须在 lambda 表达式本身之外执行它们。

我已经尝试过了,但我仍然收到 NotSupportedException,特别是

LINQ to Entities 无法识别方法 'Int32 CalculateAgeList(System.DateTime)' 方法,并且该方法不能 翻译成商店表达式。

我已尝试调试以弄清楚发生了什么,但我似乎无法完全找到问题的背景。

我的退货声明是

else
{
    int tempvalue = int.Parse(ageValue);
    return View(actors.Where((bd => CalculateAge(bd.BirthDate) == tempvalue)));
}

由于Actors.Age 没有映射,我必须根据出生日期计算年龄,这就是CalculateAge 在这里所做的:

private int CalculateAge(DateTime birthday)
{
    return ((int)(DateTime.Now - birthday).TotalDays / 365);
}

所以我认为这应该可以工作,因为我从表达式中删除了所有转换,但它仍然很适合。

我也相信这个“​​应该”像一个类似的过程一样在生成一个年龄列表以最初过滤(填充存在用于过滤的年龄下拉框)时,如下所示

var AgeList = new List<string>();
var AgeListQry = (from d in db.Actors orderby d.BirthDate select d.BirthDate)
    .ToList();
AgeList.AddRange(AgeListQry.Select(bd => CalculateAgeString(CalculateAge(bd)))
    .Distinct());
ViewBag.ageValue = new SelectList(AgeList);

对于完整的图片,它也转换为该方法的字符串,因为我不能在表达式中使用 .ToString()。

private string CalculateAgeString(int age)
{
    return age.ToString();
}

那么为什么它适用于生成年龄列表,但不适用于实际的过滤过程?这是否与我在表达中使用WhereSelect 有关?

【问题讨论】:

  • 你需要了解 Linq to Objects 和 Linq to Entities 的区别。您正在使用 Linq to Entites,因此您要编写的任何函数都需要使用 Expression's
  • 您可以通过计算将导致所需年龄的出生日期范围并使用actors.Where(a =&gt; a.BirthDate &gt;= minBirthdate &amp;&amp; a.BirthDate &lt; maxBirthdate) 来解决此问题
  • 它没有回答为什么(Scott 这样做),但您也可以使用 EntityFunctions.DiffYears 函数进行转换,然后允许实体框架使用 SQL 函数执行日期减法. msdn.microsoft.com/en-us/library/… Scott 暗指实体框架正在获取函数表达式树并将其转换为 SQL 语句的事实。 CLR 代码不会在数据库系统内执行。
  • 好的,这是我试图理解你们所说的内容(也感谢你们的回复!)。在这确实有效的情况下,我正在对字符串对象执行它 - AgeList,对吗?而我现在要做的是在“实体”上使用它,我不确定你是指变量/字段(如生日/年龄)还是演员本身?我仍在努力将所有术语牢牢记在脑海中。而且我不确定如何使用这个 DiffYears 函数,它会在表达式中还是在方法调用中?谢谢!
  • 想通了,我没有意识到.Where把它全部变成了直接SQL,所以我只是提前计算了问题,正如phoog所说,int tempvalue = int.Parse(ageValue) ; DateTime 计算年龄 = DateTime.Now.AddYears(-1*tempvalue); var test = actor.Where((bd => bd.BirthDate

标签: c# sql linq lambda notsupportedexception


【解决方案1】:

必须在 .Where 之外执行 Age 的查找(将其代码转换为 SQL 语法)

 {
 int tempvalue = int.Parse(ageValue);
 DateTime calculatedAge = DateTime.Now.AddYears(-1*tempvalue);
 var test = actors.Where((bd => bd.BirthDate < calculatedAge)).ToArray();
 return View(test);
 }

【讨论】:

    猜你喜欢
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多