Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C#从LINQ查询日期时间字段计算日期(或年份)进行比较(年龄从)_C#_Linq - Fatal编程技术网

使用C#从LINQ查询日期时间字段计算日期(或年份)进行比较(年龄从)

使用C#从LINQ查询日期时间字段计算日期(或年份)进行比较(年龄从),c#,linq,C#,Linq,请参阅calculateAge将出生日期转换为LINQ查询中的当前年龄(它适用于其他键,例如:EyeColor,但年龄转换失败),我想与存储在数组中的值进行比较。我尝试将该值存储在链接上方的DateTime temp变量中,“case”AgeTo正下方:“但是我不能接受x.profile.BirthDate值,因为它只允许在LINQ查询中使用。看起来LINQ查询在构建过程中并没有给出错误,但是,它无法 错误: LINQ to实体无法识别方法“Int32” calculateAge(System.

请参阅calculateAge将出生日期转换为LINQ查询中的当前年龄(它适用于其他键,例如:EyeColor,但年龄转换失败),我想与存储在数组中的值进行比较。我尝试将该值存储在链接上方的DateTime temp变量中,“case”AgeTo正下方:“但是我不能接受x.profile.BirthDate值,因为它只允许在LINQ查询中使用。看起来LINQ查询在构建过程中并没有给出错误,但是,它无法

错误:

LINQ to实体无法识别方法“Int32” calculateAge(System.DateTime)'方法,此方法不能为空 翻译成商店表达式

如何处理有什么帮助吗

代码和计算方法:

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,我将更改代码,以返回到您对我的成功。您是否意识到,如果您执行代码接近午夜,如果可能失败?最好只询问一次当前时间,以确保使用相同的时间比较搜索列表中的所有项目。编写一个合适的规范也更容易:“此函数计算集合中所有项目的年龄