Linq-to-SQL и таймаут DateTime

У нас действительно странное и непоследовательное поведение с 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..... и эта настройка одинакова в другом месте (например, на нашей тестовой серверной инфраструктуре).

Итак, мой вопрос:

  • Почему на земле Linq-to-SQL внезапно создает совершенно другое представление того же DateTime для отправки на SQL Server? Есть ли какая-нибудь ручка для управления этим?

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

SqlTypeException - переполнение SqlDateTime. Должно быть между 1/1/1753 12:00:00 AM и 12/31/9999 11:59:59 PM.

Кажется, это ошибка .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

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

Сначала я должен проверить:

  • Точная схема LINQ SQL/модель базы данных верна.
  • Ваша логика проблемы, чтобы убедиться, что новое значение DateTime не может быть вне диапазона. В частности, убедитесь, что он не может быть DateTime.MinValue или DateTime.MaxValue.
  • Что вы не выполняете синтаксический анализ строк до даты в своем приложении.
  • Что сервер SQL не имеет никаких триггеров (особенно вместо  триггеры, которые могут модифицировать инструкцию обновления).

Я угадываю вас (или вашего клиента), начиная с переполнения SqlTypeException - SqlDateTime. Должно быть от 1/1/1753 12:00:00 AM и 12/31/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 не содержит 'turn' в строке, поскольку он не хранит даты как строки, но внутреннее представление - это число (что-то вроде количества дней с 1 января 1900 года).

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

Кроме того, как я понимаю, если вы используете параметр DateTime (который LINQ должен иметь 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.