Странность Linq-to-SQL и DateTime - PullRequest
       22

Странность Linq-to-SQL и DateTime

15 голосов
/ 04 ноября 2011

У нас действительно странное и противоречивое поведение при Linq-to-SQL здесь.

Наше приложение установлено на сайтах нескольких клиентов, и по большей части оно работает просто отлично. Один из запросов в Linq-to-SQL обновляет таблицу и устанавливает для столбца DateTime новое значение.

Во всех случаях, включая наши системы разработки и тестирования, этот оператор Linq-to-SQL переводится во что-то вроде:

UPDATE dbo.OurTable 
SET WorkTimeStamp = @WTS 
WHERE ID = @ID

@WTS = '2011-11-04 14:15:25', @ID = 555

Однако на сайте одного клиента по причинам, которые нам не ясны (пока), это обновление переводится на:

UPDATE dbo.OurTable 
SET WorkTimeStamp = @WTS 
WHERE ID = @ID

@WTS = 'Nov  4 2011 02:15:25PM', @ID = 555

и по какой-то причине происходит сбой SQL Server 2005 .

Теперь на серверах заказчика (веб-сервер и SQL Server) установлены версии Windows Server 2008 на английском и американском языках; язык в SQL Server установлен на us_english, формат даты установлен на mdy, для учетной записи пользователя, выполняющего обновление, установлен язык English в SQL Server ..... и эта настройка такая же в другом месте (например, на нашей тестовой серверной инфраструктуре).

Итак, мой вопрос на самом деле:

  1. С какой стати Linq-to-SQL внезапно создает совершенно другое представление того же DateTime для отправки на SQL Server? Есть ли ручка, чтобы повернуть это?

  2. И почему ADO.NET и база данных SQL Server 2005 с пакетом обновления 2 (SP2) не могут правильно обработать этот оператор UPDATE? Мы получаем ошибку в нашем журнале, которая гласит:

SqlTypeException - переполнение SqlDateTime. Должно быть между 01.01.1753 12:00:00 и 31.12.9999 11:59:59 вечера.

Кажется, что это ошибка .NET (больше, чем ошибка SQL Server), и кажется, что .NET по какой-то причине не может действительно интерпретировать этот Nov 4 2011 02:15:25PM как действительный DateTime. При попытке запустить сгенерированный оператор UPDATE в SQL Server Management Studio , мы не можем «заставить» эту ошибку произойти - UPDATE счастливо работает просто отлично .....

Обновление: некоторые дальнейшие исследования показывают, что Linq-to-SQL ведет себя по-разному при переходе на SQL Server 2005 или 2008.

  • с SQL Server 2005 , наши даты превращаются в: Nov 4 2011 02:15:25PM
  • с SQL Server 2008 , наши даты превращаются в: 2011-11-04 02:15:25PM

1 Ответ

3 голосов
/ 05 ноября 2011

Я думаю, что вы можете преследовать не ту проблему.

Я бы сначала проверил:

  1. Ваша LINQ to SQL модель схемы / базы данных точна.
  2. Ваша логика проблемы, чтобы убедиться, что новое значение DateTime не может быть вне диапазона.В частности, убедитесь, что это не может быть DateTime.MinValue или DateTime.MaxValue.
  3. Что вы не выполняете никакой разбор строк в вашем приложении.
  4. Что делает SQL Serverне иметь никаких триггеров (особенно вместо триггеров, которые могли бы изменять оператор обновления).

Я предполагаю, что вы (или ваш клиент) начинаете с получения переполнения SqlTypeException - SqlDateTime.Должно быть между 01.01.1753 12:00:00 и 31.12.9999 11:59:59 PM 'сообщение об ошибке, и после расследования вы заметили разницу в способе отображения дат.

Вы не упоминаете, откуда поступает информация, поэтому я предполагаю что-то вроде профилировщика SQL.

Однако проблема с отображением даты может быть из-за красной селедки, поскольку это не должно быть проблемой.

с SQL Server 2005, наши даты превращаются в: 4 ноября 2011 02:15:25 PM

с SQL Server 2008, наши даты превращаются в: 2011-11-04 02:15:25 PM

Я не совсем уверен, что вы подразумеваете под этим.SQL не 'превращает' даты в строку, поскольку он не хранит даты в виде строк, но внутренним представлением является число (что-то вроде количества дней с 1 января 1900 года).

Если вы имеете в виду, что ваши даты отображаются как 4 ноября 2011 г. 02:15:25 PM, то это зависит от программы, которая отображает информацию.

Кроме того, насколько я понимаю, еслиВы используете параметр DateTime (который LINQ to SQL должен делать, если модель базы данных точна), тогда информация, отправляемая с клиента на SQL Server, является числовым представлением SQL DateTime.Это должно избежать любых проблем преобразования даты и времени между клиентом и сервером.Когда вы смотрите, например, на SQL Profiler, он не показывает числовое представление даты, которое будет очень мало значить для большинства людей, но пытается быть полезным и отображает значение в виде строки.

Важным моментом является то, что если SQL или профилировщику SQL удается отобразить параметр datetime как «4 ноября 2011 г. 02:15:25 PM», то он знает, что это действительная дата, и точно знает, какая это дата.

Так что я подозреваю, что проблема с форматом отображения, вероятно, не имеет значения.

Таким образом, возникает вопрос, почему ваш клиент получает сообщение об ошибке переполнения SqlTypeException - SqlDateTime.

Первоедля этого нужно проверить, какое значение даты вы устанавливаете, что необходимо сделать на уровне приложения, а не на сервере SQL Server, так как это не зашло бы так далеко.(Это еще одна причина, почему я не думаю, что это проблема конфигурации SQL.)

кажется, что .NET не может действительно интерпретировать это 4 ноября 2011 02:15:25 PM как действительный DateTimeпо какой-то причине

Я не вижу, где .NET будет даже , пытаясь интерпретировать строки как дату, если у вас нет команд DateTime.Parse иесли это так, то проблема не имеет ничего общего ни с LINQ, ни с SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...