2009-03-14 2 views
5

Я работаю над проектом ASP.NET MVC с NHibernate в качестве бэкэнд, и у меня возникли проблемы с получением некоторых дат для записи в мои таблицы базы данных SQL Server.NHibernate не будет сохраняться DateTime Переполнение SqlDateTime

Эти поля даты НЕВОЗМОЖНЫ, поэтому многие ответы здесь о том, как установить значения NULL, не помогли.

В основном, когда я пытаюсь сохранить сущность с полями DateAdded и LastUpdated, я получаю исключение переполнения SqlDateTime. У меня была аналогичная проблема в прошлом, когда я пытался написать поле datetime в столбец smalldatetime, обновив тип в столбце, чтобы устранить проблему. Я чувствую, что это будет проблема с определением таблицы или некоторым типом несовместимых типов данных, а исключение переполнения - это немного руля.

Я приложил пример определения таблицы и запроса, который NHibernate пытается запустить, будет с благодарностью принята любая помощь или предложения.

CREATE TABLE [dbo].[CustomPages](
    [ID] [uniqueidentifier] NOT NULL, 
    [StoreID] [uniqueidentifier] NOT NULL, 
    [DateAdded] [datetime] NOT NULL, 
    [AddedByID] [uniqueidentifier] NOT NULL, 
    [LastUpdated] [datetime] NOT NULL, 
    [LastUpdatedByID] [uniqueidentifier] NOT NULL, 
    [Title] [nvarchar](150) NOT NULL, 
    [Term] [nvarchar](150) NOT NULL, 
    [Content] [ntext] NULL 
) 

exec sp_executesql N'INSERT INTO CustomPages (Title, Term, Content, LastUpdated, DateAdded, StoreID, LastUpdatedById, AddedById, ID) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)',N'@p0 
nvarchar(21),@p1 nvarchar(21),@p2 nvarchar(33),@p3 datetime,@p4 datetime,@p5 uniqueidentifier,@p6 uniqueidentifier,@p7 uniqueidentifier,@p8 uniqueidentifier',@p0=N'Size and Colour 
Chart',@p1=N'size-and-colour-chart',@p2=N'This is the size and colour chart',@p3=''2009-03-14 14:29:37:000'',@p4=''2009-03-14 
14:29:37:000'',@p5='48315F9F-0E00-4654-A2C0-62FB466E529D',@p6='1480221A-605A-4D72-B0E5-E1FE72C5D43C',@p7='1480221A-605A-4D72-B0E5-E1FE72C5D43C',@p8='1E421F9E-9A00-49CF-9180-DCD22FCE7F55' 

В ответ на ответы/комментарии, я использую Fluent NHibernate и генерируемый отображение ниже

public CustomPageMap() { 

      WithTable("CustomPages"); 

      Id(x => x.ID, "ID") 
       .WithUnsavedValue(Guid.Empty) 
      . GeneratedBy.Guid(); 

      References(x => x.Store, "StoreID"); 

      Map(x => x.DateAdded, "DateAdded"); 
      References(x => x.AddedBy, "AddedById"); 
      Map(x => x.LastUpdated, "LastUpdated"); 
      References(x => x.LastUpdatedBy, "LastUpdatedById"); 


      Map(x => x.Title, "Title"); 
      Map(x => x.Term, "Term"); 
      Map(x => x.Content, "Content"); 

     } 

    <?xml version="1.0" encoding="utf-8"?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" assembly="MyNamespace.Core" namespace="MyNamespace.Core"> 
<class name="CustomPage" table="CustomPages" xmlns="urn:nhibernate-mapping-2.2"> 
<id name="ID" column="ID" type="Guid" unsaved-value="00000000-0000-0000-0000-000000000000"><generator class="guid" /></id> 
<property name="Title" column="Title" length="100" type="String"><column name="Title" /></property> 
<property name="Term" column="Term" length="100" type="String"><column name="Term" /></property> 
<property name="Content" column="Content" length="100" type="String"><column name="Content" /></property> 
<property name="LastUpdated" column="LastUpdated" type="DateTime"><column name="LastUpdated" /></property> 
<property name="DateAdded" column="DateAdded" type="DateTime"><column name="DateAdded" /></property> 
<many-to-one name="Store" column="StoreID" /><many-to-one name="LastUpdatedBy" column="LastUpdatedById" /> 
<many-to-one name="AddedBy" column="AddedById" /></class></hibernate-mapping> 
+0

Ваша таблица и SQL выглядят нормально. Выполняется ли этот SQL-запрос, если вы попытаетесь запустить его вручную? Возможно, стоит разместить здесь код и файл сопоставления спящего режима. –

+0

Да, запрос выполняется нормально в SQL Query Analyzer, за исключением того, что мне нужно сменить двойные одинарные кавычки вокруг datetime (как строки стиля utc) на одинарные кавычки, этот запрос сгенерировано nhibernate –

ответ

0

Почему @ p3 и p4 @ имеют 2x одинарные кавычки? Скопировать и вставить ошибку?

я не могу проверить (не установлен здесь SQL), но если millisecond separator не быть "точка", то есть "2009-03-14 14: 29: 37,000"

@ p3 это «раньше», @ р4 «после» здесь:

exec sp_executesql 
    N'INSERT INTO CustomPages (Title, Term, Content, LastUpdated, DateAdded, StoreID, LastUpdatedById, AddedById, ID) 
    VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)', 
    N'@p0 nvarchar(21),@p1 nvarchar(21),@p2 nvarchar(33),@p3 datetime,@p4 datetime,@p5 uniqueidentifier,@p6 uniqueidentifier,@p7 uniqueidentifier,@p8 uniqueidentifier', 

    @p0=N'Size and Colour Chart', 
    @p1=N'size-and-colour-chart', 
    @p2=N'This is the size and colour chart', 
    @p3=''2009-03-14 14:29:37:000'', --quotes + dot wrong? 
    @p4='2009-03-14 14:29:37.000', --quotes + dot correct? 
    @p5='48315F9F-0E00-4654-A2C0-62FB466E529D', 
    @p6='1480221A-605A-4D72-B0E5-E1FE72C5D43C', 
    @p7='1480221A-605A-4D72-B0E5-E1FE72C5D43C', 
    @p8='1E421F9E-9A00-49CF-9180-DCD22FCE7F55' 
+0

Да, я думал, что он визуализировал даты, был немного странным, однако он работает в анализаторе запросов, за исключением того, что мне нужно поменять двойные кавычки на одинарные кавычки. Я рассмотрел главу 5 nhibernate doco, думая, что могу сказать, что исправлять диалект, но это действительно возможно –

+0

Формат 2009-03-14 14: 29: 37: 000 неверен, хотя для SQL Server – gbn

+0

Диалект может быть вашей проблемой. Почему вы говорите, что не представляется возможным установить это? Как вы создаете свой SessionFactory? Вы читаете его из файла конфигурации или создаете его программно? –

0

SQL-скрипт в вашем вопросе выполняется нормально на моей установке SQL 2005 (когда я установил котировка вопросы подобран ГБН). И ваше отображение также выглядит отлично. Извините, что так мало помог.

0

Я использовал s # architecture/fluentnhibernate для создания этого сопоставления, я обновил его до последней версии и, похоже, работает нормально.

17

На самом деле причина сцены:

Когда NHibernate читает строки из БД, значение равно нулю, и это то, что сессия помнит. Когда объект переопределяется NHibernate, значение Date устанавливается в значение DateTime.MinValue. Когда сеанс синхронизируется с db, NHibernate предполагает, что что-то изменилось, потому что currentState и предыдущееState отличаются друг от друга и пытаются обновить строку. Что в свою очередь терпит неудачу, поскольку DateTime.MinValue не будет вписываться в столбец datetime SqlServer.

Решение: сделать ваш datetime нулевым либо путем помещения? в конце Datetime, например DateTime? или Nullable

завершена статьи можно найти по адресу: nhibernate-sqldatetime-overflow-issue

+0

Решил мою проблему. –

0

Просто FYI, я работал на переносе существующего приложения к NHibernate из множества встроенных подходов доступа к данным. Эта проблема возникла быстро, и я нашел простое решение, которое минимизировало влияние на существующий код функционального приложения. Поскольку в некоторых случаях мы перемещаемся по уровню, интерфейс класса данных должен оставаться стабильным, если это вообще возможно.Решение здесь заключалось в том, чтобы продолжать использовать типы DateTime для публичного интерфейса, добавлять методы расширения в частные типы полей для преобразования из MinValue в null и обратно в частные поля в accessors и сопоставлять nHibernate с частными полями.

JF

1

Я сталкивался с такой же выпуском таблицы с не обнуляемыми столбцами даты и времени, и переполнение SqlDateTime на ворота.

В моем случае фактическая проблема заключалась в том, что сохранение инициировало session.flush, которое вызывает обновление некоторого объекта, загруженного ранее с использованием того же сеанса. У этого объекта действительно были поля «datetime», в которых должно использоваться значение nullable datetime field.

Другими словами: попробуйте выполнить session.flush до сохранения или обновления, чтобы проверить, может быть, проблема связана с более ранним использованием одного и того же объекта сеанса.

Надежды, которые помогают кому угодно.