Проблема с запросом Linq и форматом даты - PullRequest
3 голосов
/ 16 июня 2010

У меня есть консольное приложение C #, написанное с использованием Visual Studio 2008.

Моя системная культура - en-GB.У меня есть запрос Linq, который выглядит следующим образом:

var myDate = "19-May-2010";

var cus = from x in _dataContext.testTable
     where x.CreateDate == Convert.ToDateTime(myDate)
     select x;

Результирующий запрос SQL генерирует ошибку, потому что он возвращает даты как «19/05/2010», которые он интерпретирует как неправильную дату.По какой-то причине, хотя моя системная культура настроена на en-GB, похоже, она пытается интерпретировать ее как дату en-US.

Есть идеи, как мне обойти это?

ПравитьСпасибо за комментарии о волшебных строках и злоупотреблении переменными, но это не моя проблема.Моя проблема заключается в том, что при преобразовании из Linq в SQL даты интерпретируются как даты в американском формате (19/05/2010 интерпретируется как: месяц девятнадцатый, день 5 и год 2010), что приводит к следующей ошибке:

System.Data.SqlClient.SqlException: The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value

Предложение where результирующего запроса SQL выглядит следующим образом:

WHERE ([t0].[CreateDate] = '19/05/2010 00:00:00') 

Обратите внимание, что точно такой же запрос Linq прекрасно работает в LinqPad.

Я пробовал следующееусловие where:

where x.CreateDate == DateTime.Today

и по-прежнему возникает ошибка.

Дополнительная информация:

Визуализатор запросов SQL Server:

SELECT [t0].[field1], [t0].[field2], [t0].[field3] AS [field4], [t0].[field5]
FROM [dbo].[table] AS [t0]
WHERE ([t0].[CreateDateTime] = '19/05/2010 00:00:00') 

Original query:
SELECT [t0].[field1], [t0].[field2], [t0].[field3] AS [field4], [t0].[field5]
FROM [dbo].[table] AS [t0]
WHERE ([t0].[CreateDateTime] = @p0) 
-------------------------------
@p0 [DateTime]: 19/05/2010 00:00:00

LINQPad:

-- Region Parameters
DECLARE @p0 DateTime SET @p0 = '2010-05-19 00:00:00.000'
-- EndRegion
SELECT [t0].[field1], [t0].[field2], [t0].[field3] AS [field4], [t0].[field5]
FROM [table] AS [t0]
WHERE ([t0].[CreateDateTime] = @p0)

Выше я заметил, что LinqPad представляет дату в другом формате для VS.

Спасибо.

Alan T

Ответы [ 6 ]

3 голосов
/ 16 июня 2010

Не отправляйте локальные строки в базу данных и не просите базу данных преобразовать эти строки в DateTimes.Только не.

Первоначально:

var myDate = "19-May-2010"; 

var cus = from x in _dataContext.testTable 
  where x.CreateDate == Convert.ToDateTime(myDate) 
  select x; 
  • Не злоупотребляйте var.
  • Отделяйте действия, которые вы собираетесь выполнять в базе данных, от действий, которые вы намереваетесьпроисходить локально

Итак ...

string myInput = "19-May-2010";
DateTime myDate = Convert.ToDateTime(myInput);

IQueryable<TestTable> cus =
  from x in _dataContext.testTable
  where x.CreateDate == myDate
  select x;

В ответ на обновление.

  • Похоже, ваше приложение отправляетправильно отформатированные даты и время, но при этом используется соединение, которое ожидает неправильно отформатированные даты и времени.
  • Вы можете изменить каждое соединение или изменить настройки по умолчанию для входа в систему: http://support.microsoft.com/kb/173907
2 голосов
/ 16 июня 2010

Короткий ответ: «не используйте строки для представления дат».

Предполагая, что столбец CreateDate представляет собой дату и время SQL Server, вы должны просто выполнить сравнение с классом .NET DateTime.

1 голос
/ 16 июня 2010

Вы можете использовать:

x.CreateDate == DateTime.ParseExact(myDate, "dd-MMM-yyyy", System.Globalization.CultureInfo.InvariantCulture);

Это, конечно, предполагает, что ваша дата в БД совпадает с вашим полем myDate (т. Е. Если у вас есть время, включенное в дату, вам нужно будет изменить вышеуказанное, чтобы включить часть времени).

0 голосов
/ 20 июня 2010

Я знаю, что вы, вероятно, проверяли это, но можете ли вы проверить следующее:

  1. CreateDate объявлен как DateTime или DateTime2 в базе данных
  2. Свойство CreateDate в вашем классе Linqedобъявляется как .NET DateTime
  3. System.Linq.Mapping.ColumnAttribute правильно определен для вашего свойства CreateDate в вашем классе Linqed up.

На основании того факта, что вы 'Я вижу, что с запросом в LinqPad успешно выполняется запрос, я подозреваю, что что-то не так со свойством CreateDate или определением SQL этого поля.Я ДЕЙСТВИТЕЛЬНО подозреваю, что ваш вывод Linq-to-SQL говорит «WHERE ([t0]. [CreateDate] = '19 / 05/2010 00:00:00 ')» вместо «WHERE ([t0]. [CreateDate»).] = @ p0) ".

0 голосов
/ 17 июня 2010

Что происходит, когда вы пытаетесь это

var myDate = "20100519"; 

var cus = from x in _dataContext.testTable 
     where x.CreateDate == Convert.ToDateTime(myDate) 
     select x; 
0 голосов
/ 16 июня 2010

Как сказал Билл, не используйте строки для представления дат.LINQ to SQL использует параметризованные запросы для передачи параметров, поэтому у вас не должно возникнуть проблем с локалями - при условии, что в поле вашей базы данных и вашем параметре указаны обе даты.

Вы можете проверить сгенерированный оператор SQL, прикрепив объект TextWriter (например, Console.Out) к свойству Log объекта DataContext. Следующий код

using(var datacontext=new DatesDataContext())
{
    var myDate=DateTime.Today;
    //Or, to specify a date without string parsing
    //var myDate=new DateTime(2010,6,16);
    var dates = from date in datacontext.DateTables
        where date.DateField == myDate                 
        select date;

    datacontext.Log = Console.Out;
    foreach (var date in dates)
    {
        Console.WriteLine(date.DateField);
    }
}

создал этот запрос

SELECT [t0].[DateField]
FROM [dbo].[DateTable] AS [t0]
WHERE [t0].[DateField] = @p0
-- @p0: Input DateTime (Size = -1; Prec = 0; Scale = 0) [6/16/2010 12:00:00 AM]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

Как видите, запрос имеет параметр типа DateTime и возвращает правильные записи.

Что именно является ошибкой, с которой вы столкнулись?Получаете ли вы исключение или неверные результаты?Если вы не получаете результатов, возможно, поле вашей базы данных содержит значение времени, и в этом случае оно не будет соответствовать параметру, который содержит только значение даты

...