LINQ 表达式无法翻译

时间:2021-04-05 19:26:05

标签: c# sql linq .net-core

我编写了以下 LINQ 表达式:

        var data = await _context.Occurrence
        .Include(o => o.Expense)
        .Where(o => 
            ((o.RepeatStart.Date - date.Date).TotalHours % o.RepeatInterval == 0) 
            ||
                o.RepeatYear == date.Year || o.RepeatYear < 0
                &&
                o.RepeatMonth == date.Month || o.RepeatMonth < 0
                &&
                o.RepeatDay == date.Day || o.RepeatDay < 0
                &&
                o.RepeatWeek == ISOWeek.GetWeekOfYear(date) || o.RepeatWeek < 0
                &&
                o.RepeatWeekDay == (int)date.DayOfWeek || o.RepeatWeekDay < 0
                &&
                o.RepeatStart.Date <= date.Date
        )
        .Select(e => e.Expense)
        .ToListAsync();

我收到此错误: could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable()

但是,我没有收到任何运行时或编译时错误。我做错了什么?

1 个答案:

答案 0 :(得分:-1)

您正在 WHERE 子句中调用特定于 C# 的功能。实体框架无法将其转换为纯 SQL,并要求您在应用中使用 AsEnumerable() 进行过滤,而不是尝试将其转换为 SQL。

您应该能够简单地开始工作,但必须遵守:

   var data = await _context.Occurrence
    .Include(o => o.Expense)
    .AsEnumerable()
    .Where(o => 
        ((o.RepeatStart.Date - date.Date).TotalHours % o.RepeatInterval == 0) 
        ||
            o.RepeatYear == date.Year || o.RepeatYear < 0
            &&
            o.RepeatMonth == date.Month || o.RepeatMonth < 0
            &&
            o.RepeatDay == date.Day || o.RepeatDay < 0
            &&
            o.RepeatWeek == ISOWeek.GetWeekOfYear(date) || o.RepeatWeek < 0
            &&
            o.RepeatWeekDay == (int)date.DayOfWeek || o.RepeatWeekDay < 0
            &&
            o.RepeatStart.Date <= date.Date
    )
    .Select(e => e.Expense)
    .ToList();

然而,这将下载整个出现表。您应该将其重组如下:

var data = await _context.Occurrence
    .Include(o => o.Expense)
    .Where(o => /* SQL-friendly calls only */)
    .AsEnumerable()
    .Where(o => /* everything else */)
    .Select(e => e.Expense)
    .ToList();