2009-03-14 16 views
5

Estoy trabajando en un proyecto ASP.NET MVC con NHibernate como servidor y estoy teniendo problemas para obtener algunas fechas para escribir de nuevo en las tablas de mi base de datos de SQL Server.NHibernate no persistirá DateTime SqlDateTime overflow

Estos campos de fecha NO son NULL, por lo que las muchas respuestas aquí acerca de cómo configurar las fechas de fecha anulables no han ayudado.

Básicamente, cuando intento guardar la entidad que tiene los campos DateAdded y LastUpdated, obtengo una excepción de desbordamiento SqlDateTime. He tenido un problema similar en el pasado cuando intentaba escribir un campo de fecha y hora en una columna de fecha pequeña, actualizando el tipo en la columna que parecía solucionar el problema. Mi intuición es que va a haber algún problema con la definición de la tabla o algún tipo de tipos de datos incompatibles, y la excepción de desbordamiento es un poco vagabundo.

He adjuntado un ejemplo de la definición de la tabla y la consulta que NHibernate está tratando de ejecutar, cualquier ayuda o sugerencia sería muy apreciada.

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' 

En respuesta a los comentarios de las respuestas /, estoy usando NHibernate Fluido y el mapeo generada está por debajo

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

Su tabla y el SQL parecen estar bien. ¿Funciona esa consulta SQL si intentas ejecutarla a mano? Podría valer la pena publicar aquí el código y el archivo de mapeo de hibernación –

+0

Sí, la consulta funciona bien en el Analizador de consultas SQL, excepto que tengo que cambiar las comillas simples dobles alrededor de las fechas (como cadenas de estilo utc) para comillas simples, esta consulta es generado por nhibernate –

Respuesta

0

¿Por qué @ P3 y P4 @ tienen comillas simples 2x? Copiar y pegar el error?

No puedo comprobar (no tiene SQL instalado aquí), pero debería ser el millisecond separator no "punto", es decir, "2009-03-14 14: 29: 37.000"

@ p3 es "antes", @ p4 es "después de" aquí:

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

Sí, pensé que la forma en que representaba las fechas también era un poco extraña, sin embargo funciona en el analizador de consultas, excepto que tengo que cambiar las comillas dobles para comillas simples. Miré en el capítulo 5 del doco nhibernate pensando que podría decir a nhibernate cómo corregir el dialecto, pero parece posible –

+0

El formato 14/03/2009 14: 29: 37: 000 es incorrecto aunque para SQL Server – gbn

+0

El dialecto podría ser tu problema ¿Por qué dices que no parece posible establecer eso? ¿Cómo está creando su SessionFactory? ¿Lo está leyendo desde un archivo de configuración o lo está creando mediante programación? –

0

La secuencia de comandos SQL en su pregunta ejecutado muy bien en mi instalación de SQL 2005 (una vez que fija los temas de cotización recogidos por GBN). Y su mapeo también se ve bien. Perdón por ser de tan poca ayuda.

0

Estaba usando s # architecture/fluentnhibernate para crear esta asignación, me he actualizado a la última versión y parece estar funcionando bien.

17

En realidad, la razón detrás de la escena es:

Cuando NHibernate lee la fila de la db, el valor es nulo, y eso es lo que recuerda la sesión. Cuando NHibernate rehidrata el objeto, la fecha se establece en el valor DateTime.MinValue. Cuando la sesión se sincroniza con el archivo db, NHibernate supone que algo ha cambiado, porque el estado actual y el estado anterior son diferentes e intenta actualizar la fila. Lo cual a su vez falla, porque DateTime.MinValue no cabe en una columna de SqlServer datetime.

La solución: hace que su datetime se pueda anular al ponerlo? al final de Datetime como DateTime? o anulable

Artículo completo se puede encontrar en: nhibernate-sqldatetime-overflow-issue

+0

Ha solucionado mi problema. –

0

Como digo, he estado trabajando en la migración de una aplicación existente para NHibernate de una variedad de embebido de acceso a datos se acerca. Este problema surgió rápidamente y encontré una solución fácil que minimizaba el impacto en el código de aplicación funcional existente. Debido a que estamos migrando por capas en algunos casos, la interfaz de la clase de datos debe permanecer estable si es posible.La solución aquí era continuar utilizando los tipos DateTime para la interfaz pública, agregar métodos de extensión a los tipos de campo privados para convertir de MinValue a null y viceversa en los campos privados en los accessors, y mapear nHibernate a los campos privados.

JF

1

que se enfrentaron a la misma mesa problema con columnas de fecha y hora no anulables y un desbordamiento de SqlDateTime en una reserva.

En mi caso, el problema real fue que el guardado desencadenó un session.flush que provoca una actualización de algún objeto cargado anteriormente utilizando la misma sesión. Este objeto tenía el problema de 'campos de fecha y hora cuando el campo de fecha y hora de nullable debería haberse utilizado'.

En otras palabras: intente realizar una sesión.flush antes de guardar o actualizar para comprobar si el problema puede deberse al uso anterior del mismo objeto de sesión.

Espero que ayude a nadie.

Cuestiones relacionadas