NHibernate не будет сохраняться переполнение DateTime SqlDateTime - PullRequest
5 голосов
/ 14 марта 2009

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

Эти поля даты НЕ обнуляемы, поэтому многие ответы здесь о том, как настроить обнуляемые даты и времени, не помогли.

Обычно, когда я пытаюсь сохранить сущность с полями 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>

Ответы [ 6 ]

17 голосов
/ 27 июля 2009

На самом деле причина этого сценария:

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

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

Полная статья может быть найдена в: nhibernate-sqldatetime-overflow-Issue

1 голос
/ 21 сентября 2011

Я столкнулся с той же таблицей ошибок с необнуляемыми столбцами datetime и переполнением SqlDateTime при сохранении.

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

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

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 23 апреля 2010

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

JF

0 голосов
/ 19 апреля 2009

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

0 голосов
/ 17 марта 2009

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

0 голосов
/ 14 марта 2009

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

Я не могу проверить (здесь не установлен SQL), но если разделитель миллисекунд не будет "точкой", то есть "2009-03-14 14: 29: 37.000"

@ p3 здесь «до», @ p4 здесь «после»:

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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...