【发布时间】: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();
}
那么为什么它适用于生成年龄列表,但不适用于实际的过滤过程?这是否与我在表达中使用Where 和Select 有关?
【问题讨论】:
-
你需要了解 Linq to Objects 和 Linq to Entities 的区别。您正在使用 Linq to Entites,因此您要编写的任何函数都需要使用
Expression's -
您可以通过计算将导致所需年龄的出生日期范围并使用
actors.Where(a => a.BirthDate >= minBirthdate && a.BirthDate < 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