Преобразование Linq в Entities DateTime

Если задан объект с DateTime в виде строки, каковы мои варианты фильтрации данных с помощью LINQ to Entities по дате?

Кажется, это не поддерживает меня в преобразованиях DateTime.

В принципе, я хочу выполнить:

var filtered = from item in entities.itemsSet
               where Convert.ToDateTime(shift.starttime) >= startDate 
                   && Convert.ToDateTime(shift.endtime) < endDate
               select item;

Каковы мои варианты для достижения этого?


person LB.    schedule 31.03.2010    source источник
comment
какую ошибку вы получаете, если есть?   -  person BlackICE    schedule 31.03.2010
comment
В основном по линиям Linq to entity не поддерживает (Convert.ToDateTime(String))...   -  person LB.    schedule 31.03.2010


Ответы (3)


В конечном итоге вы закончите фильтрацию памяти.

//So first select your data

var data= (from item in entities.itemsSet).ToList();


//Then filter
var filtered = from item in data
           where Convert.ToDateTime(shift.starttime) >= startDate 
               && Convert.ToDateTime(shift.endtime) < endDate
           select item;

Другой вариант — создать хранимую процедуру, которая сделает это за вас. В SP вам нужно будет взять начало/конец, а затем сравнить его со строками даты и времени, преобразованными в дату и время.

person Nix    schedule 31.03.2010
comment
Мне это нравится. Хотя могут быть проблемы с масштабированием, это будет работать. Путь SP, вероятно, путь. - person LB.; 01.04.2010
comment
Полностью согласен, но первая битва будет за изменение типа БД на актуальное время! - person Nix; 01.04.2010
comment
И, к вашему сведению, приведенный выше код можно упростить до одного запроса... просто выполнив var filtered = (выберите элемент из entity.itemsSet.AsEnumarable() - person Nix; 01.04.2010
comment
Я не могу изменить тип БД на время, потому что у клиента он такой =) - person LB.; 01.04.2010
comment
И у нас есть к нему доступ только для чтения, так как они не собираются менять свою схему. - person LB.; 01.04.2010
comment
После фильтрации в памяти, как вы конвертируете обратно в LINQtoEntities? Поскольку .ToList() просто преобразуется в LINQtoObjects. - person LB.; 01.04.2010
comment
Не уверен, что понял твой вопрос? Они по-прежнему будут сущностями, когда я сказал превратить их в объекты, я имею в виду, продолжайте и выберите их из базы данных, а затем отфильтруйте. - person Nix; 01.04.2010
comment
Отлично.... Я столько раз пытался использовать Convert.TodateTime в моем запросе linq to entites, но у меня это не работает...... - person Enigma State; 25.06.2012

Используйте System.Data.Objects.SqlClient.SqlFunctions

Существует функция DateDiff, которая имеет перегрузки для приема строк в качестве дат.

Все функции внутри класса SqlFunctions компилируются в операторы SQL и могут использоваться только внутри Linq to entity.

[EdmFunctionAttribute("SqlServer", "DATEDIFF")]
public static Nullable<int> DateDiff(string datePartArg, string startDate, string endDate)

http://msdn.microsoft.com/en-us/library/dd466158.aspx

Вам нужно будет передать строку типа «день» в качестве первого параметра, указывающего часть даты для сравнения. Функция напрямую сопоставляется с функцией SQL DATEFIFF:

http://msdn.microsoft.com/en-us/library/ms189794.aspx

Существует аналогичный класс для Linq to SQL, просто предупреждаю вас.

person Marcus10110    schedule 20.03.2012
comment
Неато! Это спасло меня при использовании linq-to-entities для запроса сравнения дат по датам, хранящимся в столбце varchar. - person anewcomer; 03.08.2012

У меня была та же проблема, потому что текущий поставщик данных сервера Sql для EF пренебрегает переводом DateTime.Parse в CAST (varField As DateTime).

Итак, чтобы построить дерево выражений, которое можно было бы успешно преобразовать в выражение хранилища, я применил следующее, которое ведет себя так же, как и следовало ожидать от предиката: DateTime.Parse(x.DateField) == DateConstraint

ПРИМЕЧАНИЕ. Объект «Клиент» содержит входные параметры для создания предиката для использования в: EFQuery.Where(predicate)

if (client.DateOfBirth.HasValue) // can't find a string <-> DateTime conversion syntax with EF support

         {

            var day = client.DateOfBirth.Value.Day.ToString().PadLeft(2, '0');

            var month = client.DateOfBirth.Value.Month.ToString().PadLeft(2, '0');

            var year = client.DateOfBirth.Value.Year.ToString();

            // very verbose, but apparently there's no EF support for String to DateTime conversion

            spec = spec.And(c => SqlFunctions.IsDate(c.DateOfBirth).HasValue && SqlFunctions.IsDate(c.DateOfBirth).Value == 1

               && c.DateOfBirth.StartsWith(day)

               && month == (c.DateOfBirth.Contains("-") || c.DateOfBirth.Contains("/")

               ? c.DateOfBirth.Substring(c.DateOfBirth.Contains("-") ? c.DateOfBirth.IndexOf("-") + 1 : c.DateOfBirth.Contains("/")

               ? c.DateOfBirth.IndexOf("/") + 1 : 0, 2) : "f")

               && c.DateOfBirth.EndsWith(year));

         }

Как вы можете видеть, приведенный выше пример выполняет сопоставление строк для компонентов даты, месяца и года и ожидает представления в формате ДД/ММ/ГГГГ (австралийца, австралийца, австралийца!). Его можно легко изменить для работы с различными представлениями даты и/или включения ограничений для компонента «Время».

person DotNet Dave    schedule 16.02.2011