.net Core 3.1 Выражение Linq «… не удалось перевести». Исключение

#linq #asp.net-core

#linq #asp.net-core

Вопрос:

 var asd = (from a in _context.Nodes
           where (Convert.ToDateTime(a.NodeProcessTime).Date >= DateTime.Now.Date.AddMonths(-5) amp;amp; Convert.ToDateTime(a.NodeProcessTime).Date <= DateTime.Now.Date.AddMonths(-4))
           select a).Count();
 

Я пытаюсь подсчитать количество записей между двумя датами. Но ниже приведено исключение. NodeProcessTime — это строка. Необходимо преобразовать в дату и время. Я что-то упускаю из виду?

Система.Исключение InvalidOperationException: ‘Выражение LINQ’, где ( источник: DbSet, предикат: (n) => Текущее время (n.NodeProcessTime).Дата> = DateTime.Now.Date.AddMonths(-5) amp;amp; ToDateTime(n.NodeProcessTime).Дата <= Дата-время.Сейчас.Дата.AddMonths(-4))’не удалось перевести. Либо перепишите запрос в форме, которую можно преобразовать, либо переключитесь на оценку клиента явно, вставив вызов AsEnumerable() , AsAsyncEnumerable(), ToList() или ToListAsync() .

Комментарии:

1. Насколько я знаю, это критическое изменение. В дальнейшем невозможно использовать вещи, которые нельзя перевести в SQL, такие как эти манипуляции с датой. Смотрите здесь

2. Я перепробовал их все, но они не работают. Спасибо.

Ответ №1:

Вы могли бы сделать что-то вроде этого:

 
// Convert (I asumme) string to date 
Date ToDate(string dateTime) => Convert.ToDateTime(dateTime).Date;

// Offset current datetime
Date OffsetNow(int offset) => DateTime.Now.Date.AddMonths(offset);

// Check date is between range
bool IsBetween(Date d) => ToDate(d) >= OffsetNow(-5) amp;amp; ToDate(d) <= OffsetNow(-4);


var asd = _context.Nodes.Count(n => IsBetween(n));


 

Ответ №2:

вы должны использовать sqlFunction для его перевода.

 SqlFunctions.DateAdd("day", 0 ,  a.NodeProcessTime)
 

просто добавьте нулевой день в свой столбец string

Ответ №3:

             List<DateTime> dateTimes = new List<DateTime>();
           
            foreach (var item in _context.Nodes.ToList())
            {
                dateTimes.Add(Convert.ToDateTime(item.NodeScanDateTime.Substring(0, 10)));
            };
            int counts = dateTimes.Where(a => a > DateTime.Now.AddMonths(-5)amp; a < DateTime.Now.AddMonths(-4)).Count();
 

Теперь сначала я получаю строку NodeScanDateTime для всех узлов и помещаю их в список. После этого я сокращаю их как тип «10.05.2020» с помощью substring и преобразую их в DateTime. Затем я сделал свой запрос, и теперь он работает. Спасибо за все…