使用C#从LINQ查询日期时间字段计算日期(或年份)进行比较(年龄从)
请参阅calculateAge将出生日期转换为LINQ查询中的当前年龄(它适用于其他键,例如:EyeColor,但年龄转换失败),我想与存储在数组中的值进行比较。我尝试将该值存储在链接上方的DateTime temp变量中,“case”AgeTo正下方:“但是我不能接受x.profile.BirthDate值,因为它只允许在LINQ查询中使用。看起来LINQ查询在构建过程中并没有给出错误,但是,它无法 错误: LINQ to实体无法识别方法“Int32” calculateAge(System.DateTime)'方法,此方法不能为空 翻译成商店表达式 如何处理有什么帮助吗 代码和计算方法:使用C#从LINQ查询日期时间字段计算日期(或年份)进行比较(年龄从),c#,linq,C#,Linq,请参阅calculateAge将出生日期转换为LINQ查询中的当前年龄(它适用于其他键,例如:EyeColor,但年龄转换失败),我想与存储在数组中的值进行比较。我尝试将该值存储在链接上方的DateTime temp变量中,“case”AgeTo正下方:“但是我不能接受x.profile.BirthDate值,因为它只允许在LINQ查询中使用。看起来LINQ查询在构建过程中并没有给出错误,但是,它无法 错误: LINQ to实体无法识别方法“Int32” calculateAge(System.
if (searchList.Count > 0)
{
foreach (KeyValuePair<String, String> kvp in searchList)
{
switch (kvp.Key)
{
case "AgeFrom":
photosquery = photosquery.Where(x => calculateAge(Convert.ToDateTime(x.profile.BirthDate)) >= Convert.ToInt32(kvp.Value));
break;
case "AgeTo":
photosquery = photosquery.Where(x => calculateAge(Convert.ToDateTime(x.profile.BirthDate)) <= Convert.ToInt32(kvp.Value));
break;
case "EyeColor":
photosquery = photosquery.Where(x => x.physical.EyesColor.Contains(kvp.Value));
break;
}
}
}
//My code for calculateAge:
public static int calculateAge(DateTime birthDay)
{
int years = DateTime.Now.Year - birthDay.Year;
if ((birthDay.Month > DateTime.Now.Month) || (birthDay.Month == DateTime.Now.Month && birthDay.Day > DateTime.Now.Day))
years--;
return years;
}
if(searchList.Count>0)
{
foreach(搜索列表中的KeyValuePair kvp)
{
开关(kvp.键)
{
案例“AGEFORM”:
photoquery=photoquery.Where(x=>calculateAge(Convert.ToDateTime(x.profile.BirthDate))>=Convert.ToInt32(kvp.Value));
打破
案例“AgeTo”:
photoquery=photoquery.Where(x=>calculateAge(Convert.ToDateTime(x.profile.BirthDate))x.physical.EyesColor.Contains(kvp.Value));
打破
}
}
}
//我的calculateAge代码:
公共静态整数计算(日期时间生日)
{
int years=DateTime.Now.Year-生日.Year;
if((birth.Month>DateTime.Now.Month)| |(birth.Month==DateTime.Now.Month&&birth.Day>DateTime.Now.Day))
年--;
回归年;
}
出现此错误的原因是在实体queryable上调用了Where
-子句,而它不知道如何将C代码转换为数据库语言的等效代码
如果能够将该函数的内部重写为没有基于.NET的变量存储或仅引用数据库中可用的CLR函数的内容,则可以内联使用该函数,就像没有函数调用一样:
var now = DateTime.Now;
...
case "AgeFrom":
photosquery = photosquery.Where(x => DbFunctions.DiffYears(x.profile.BirthDate,now) >= Convert.ToInt32(kvp.Value));
break;
如果您想使用现有的代码,则需要在筛选之前检索所有数据,这通常是不推荐的。您仍然可以通过在.Where(..)子句之前调用.ToList()来实现这一点。出现此错误的原因是在实体查询表上调用了
Where
-子句,而它不知道如何将C代码转换为数据库语言的等效代码
如果能够将该函数的内部重写为没有基于.NET的变量存储或仅引用数据库中可用的CLR函数的内容,则可以内联使用该函数,就像没有函数调用一样:
var now = DateTime.Now;
...
case "AgeFrom":
photosquery = photosquery.Where(x => DbFunctions.DiffYears(x.profile.BirthDate,now) >= Convert.ToInt32(kvp.Value));
break;
如果您想使用现有的代码,则需要在筛选之前检索所有数据,这通常是不推荐的。您仍然可以通过在.Where(..)子句之前调用.ToList()来实现这一点。您使用的是
IQueryable
,因此在具体化之前不能将其与任意C
代码混合使用
现在您有两个选择:
ToList
或ToArray
将所有数据加载到应用程序内存中,并应用过滤方法sql
函数(本例中为DATEPART
)开关之前)
:
然后,当您输入开关时,您可以写入:
case "AgeFrom":
photosquery = newQuery
.Where(x => x.yearsDiff >= Convert.ToInt32(kvp.Value))
.Select(x => x.AllQuery );
break;
您使用的是IQueryable
,因此在具体化之前不能将其与任意C#
代码混合使用
现在您有两个选择:
使用ToList
或ToArray
将所有数据加载到应用程序内存中,并应用过滤方法
重写查询以使用一些sql
函数(本例中为DATEPART
)
第二种方法是编写此查询(在开关之前)
:
然后,当您输入开关时,您可以写入:
case "AgeFrom":
photosquery = newQuery
.Where(x => x.yearsDiff >= Convert.ToInt32(kvp.Value))
.Select(x => x.AllQuery );
break;
有一个更简单的解决办法。与其比较年龄,不如比较日期本身
case "AgeFrom":
var fromAge = Convert.ToInt32(kvp.Value);
var maxDate = DateTime.Today.AddYears(-fromAge);
photosquery = photosquery.Where(x => x.profile.BirthDate <= maxDate);
break;
case "AgeTo":
var toAge = Convert.ToInt32(kvp.Value);
var minDate = DateTime.Today.AddYears(-toAge-1).AddDays(1);
photosquery = photosquery.Where(x => x.profile.BirthDate >= minDate);
break;
case“AgeFrom”:
var fromAge=Convert.ToInt32(kvp.Value);
var maxDate=DateTime.Today.AddYears(-fromAge);
photoquery=photoquery.Where(x=>x.profile.BirthDate x.profile.BirthDate>=minDate);
打破
这样做的另一个好处是可以进行查询,因此可以使用索引,前提是您已经在BirthDate
字段中创建了索引。有一个更简单的解决方案。与其比较年龄,不如比较日期本身
case "AgeFrom":
var fromAge = Convert.ToInt32(kvp.Value);
var maxDate = DateTime.Today.AddYears(-fromAge);
photosquery = photosquery.Where(x => x.profile.BirthDate <= maxDate);
break;
case "AgeTo":
var toAge = Convert.ToInt32(kvp.Value);
var minDate = DateTime.Today.AddYears(-toAge-1).AddDays(1);
photosquery = photosquery.Where(x => x.profile.BirthDate >= minDate);
break;
case“AgeFrom”:
var fromAge=Convert.ToInt32(kvp.Value);
var maxDate=DateTime.Today.AddYears(-fromAge);
photoquery=photoquery.Where(x=>x.profile.BirthDate x.profile.BirthDate>=minDate);
打破
这样做的另一个好处是可以进行查询,因此它可以利用索引,假设您已经在BirthDate
字段上创建了索引。您确实意识到,如果您在午夜附近执行代码,if可能会失败?最好只询问一次当前时间,以确保使用相同的时间比较搜索列表中的所有项目。更容易编写一个合适的规范:“此函数计算调用该函数时集合中所有项的年龄”。结果是可以预测的,无论您的过程执行得有多快。此外,考虑使用DATETIME。今天,代替DATEMEM.NoWooPoT,我将更改代码,以返回到您对我的成功。您是否意识到,如果您执行代码接近午夜,如果可能失败?最好只询问一次当前时间,以确保使用相同的时间比较搜索列表中的所有项目。编写一个合适的规范也更容易:“此函数计算集合中所有项目的年龄