c# - tutorial - how to use entity framework in mvc
error ''datetime2'' cuando se utiliza el marco de entidades en VS 2010.net 4.0 (16)
¿Hay una propiedad ModifiedTime en su entidad, que solo se actualiza en el lado de la base de datos? Si es así, debe usar DatabaseGeneratedOption.Computed (para EF CodeFirst). También visite este https://stackoverflow.com/a/9508312/1317263
Gracias.
Obteniendo este error:
System.Data.SqlClient.SqlException: la conversión de un tipo de datos datetime2 a un tipo de datos datetime resultó en un valor fuera de rango.
Mi entidad objeta toda la línea hasta los objetos DB.
Solo encontré una sola referencia a este error a través de Google:
Después de leer esto, recuerdo que añadimos 2 campos y luego actualizamos el modelo de entidad de VS 2010. No estoy seguro de qué quiere decir con "codificar a mano" las diferencias. No veo ninguno.
Todo lo que estoy haciendo en el código es poblar el objeto de entidad y luego guardarlo. (También llené los nuevos campos en el código) Completé el campo de fecha con DateTime.Now
...
La parte importante del código es esta: ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
La base de datos es SQL Server 2008.
¿Pensamientos?
El resto del error:
en System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, IEntityAdapter adapter) en System.Data.EntityClient.EntityAdapter.Update (IEntityStateManager entityCache) en System.Data.Objects.ObjectContext.SaveChanges (opciones de SaveOptions) en SafariAdmin.Site.WebServices.SpeciesPost.SaveOrUpdateSpecies (String sid, String fieldName, String authToken) en SpeciesPost.svc.cs: línea 58 en SafariAdmin.TestHarness.Tests.Site.WebServices.SpeciesPostSVC_Tester.SaveNewSpecies () en SpeciesPostSVC_Tester.cs: línea 33 --SqlException en System.Data.SqlClient.SqlConnection.OnError (excepción SqlException, Boolean breakConnection) en System.Data.SqlClient.SqlInternalConnection.OnError (excepción SqlException, Boolean breakConnection) en System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () en System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateO bj) en System.Data.SqlClient.SqlDataReader.ConsumeMetaData () en System.Data.SqlClient.SqlDataReader.get_MetaData () en System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) en System.Data .SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) en System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) en System.Data. SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, método String) en System.Data.SqlClient.SqlCommand.ExecuteReader (comportamiento CommandBehavior, método String) en System.Data.SqlClient.SqlCommand.ExecuteDbDataReader (comportamiento CommandBehavior) en System.Data.Common.DbCommand.ExecuteReader (comportamiento CommandBehavior) en System.Data.Mapping.Update.Internal.DynamicUpdateComma nd.Execute (Traductor de UpdateTranslator, conexión de EntityConnection, valores
2 identifierValues, List
Dictionary2 identifierValues, List
, valores generados de2 identifierValues, List
1) en System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, IEntityAdapter adapter)
Al usar primero el código del marco Entity, asígnelo:
public Nullable<System.DateTime> LastLogin { get; set; }
Asegúrese de que ninguno de los campos no nulos en la base de datos (datetime) se omita durante la inserción / actualización. Tuve el mismo error y al insertar valores en esos campos de fecha y hora se solucionó el problema. Esto ocurre si a los campos de fecha y hora no nulos no se les asigna un valor adecuado.
Después de tratar de resolver este problema durante varios días, ¿utilicé DateTime?
como el tipo de datos en mi modelo con Entity Framework Code-First en lugar de DateTime
.
Dos soluciones:
Declare las propiedades de su clase como a continuación y cree una base de datos de actualización:
public DateTime? MyDate {get; set;}
O establezca una fecha para la propiedad en el método Seed que rellena la base de datos, sin necesidad de actualizar la base de datos:
context.MyClass.AddOrUpdate(y => y.MyName,new MyClass { MyName = "Random", MyDate= DateTime.Now })
Entity framework maneja todas las fechas como Datetime2, por lo tanto, si sus campos en la base de datos son de fecha y hora, esto podría ser un problema. Tuvimos el mismo problema aquí, y por lo que encontramos, rellenar todos los campos de fecha y cambiar el tipo de datos, son las soluciones más comunes.
Esto sigue de la respuesta de stepanZ ... Recibí este error cuando uso Entity Framework Code First
con AutoMapper
.
Al configurar AutoMapping
, hemos createddt
, updateddt
, createdby
y updatedby
campos que se configuran automáticamente en nuestra public override int SaveChanges()
. Al hacer esto, debes asegurarte de que estos campos sean ignorados por AutoMapper
, de lo contrario la base de datos se actualizará con null
para esos campos cuando no se suministren desde la View
.
Mi problema era que había puesto el origen y el destino por el camino equivocado, por lo tanto, trataba de ignorar los campos al configurar ViewModel
, en lugar de al configurar el Model
.
El Mapping
veía así cuando recibí este error (nota: el cfg.CreateMap<Source, Destination>()
en la segunda línea está mapeando el Model
al ViewModel
y configurando Ignore()
)
cfg.CreateMap<EventViewModel, Event>();
cfg.CreateMap<Event, EventViewModel>()
.ForMember(dest => dest.CreatedBy, opt => opt.Ignore())
.ForMember(dest => dest.CreatedDt, opt => opt.Ignore())
.ForMember(dest => dest.UpdatedBy, opt => opt.Ignore())
.ForMember(dest => dest.UpdatedDt, opt => opt.Ignore());
El origen y el destino se deben ignorar para una asignación de ViewModel
a Model
(nota: el código siguiente es correcto donde se coloca Ignore()
contra la asignación para ViewModel
al Model
)
cfg.CreateMap<Event, EventViewModel>();
cfg.CreateMap<EventViewModel, Event>()
.ForMember(dest => dest.CreatedBy, opt => opt.Ignore())
.ForMember(dest => dest.CreatedDt, opt => opt.Ignore())
.ForMember(dest => dest.UpdatedBy, opt => opt.Ignore())
.ForMember(dest => dest.UpdatedDt, opt => opt.Ignore());
Lo que sea que encaje en un datetime encajará en un tipo de datos datetime2, viceversa, este no es el caso, puede incluir una fecha de enero de 1500 en un tipo de datos datetime2 pero datetime solo se remonta a 1753, una columna datetime2 puede volver atrás. camino al año 1. Verificaría cuál es la fecha mínima que está pasando y si sus tablas tienen columnas del tipo de datos datetime2 o datetime
Otra posible solución es establecer el tipo de columna sql del campo en datetime2. esto se puede hacer usando fluentapi.
Property(x => x.TheDateTimeField)
.HasColumnType("datetime2");
Nota: Esta es una solución para sql server 2008 en adelante ya que datetime2 no está disponible para SQL Server 2005 o posterior.
Sé que es una vieja pregunta, pero como busqué en Google aquí, alguien más podría hacer lo mismo ;-) Para los que cambiar de DateTime a DateTime2 no es una opción (como para los usuarios de SQL2005), creo que en la mayoría de los casos es más razonable para poblar los campos que quedan vacíos con algo como (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue
y no con DateTime.now, ya que es más fácil reconocerlo como un valor "pseudo nulo" (y si es necesario convertirlo a un null real en una clase parcial de objeto padre)
Sencillo. En su código primero, establezca el tipo de DateTime en DateTime ?. Por lo tanto, puede trabajar con el tipo de fecha y hora anulable en la base de datos.
Si está utilizando Code First, debe declarar cualquier propiedad DateTime
opcional como DateTime?
o Nullable<DateTime>
. Los objetos Unset DateTime
pueden causar problemas.
Si la propiedad es anulable en la base de datos y un DateTime
estándar en el código (no DateTime?
), ADO.NET enviará un comando insert con una fecha de 0001-01-01 (no NULL
), pero el valor mínimo de SQL DateTime es 1753 -01-01, causando un error. Si su propiedad DateTime
en el código es nulable (por ejemplo, DateTime?
O Nullable<DateTime>
), el comando insert intentará insertar un NULL
lugar de una fecha fuera de rango.
Tuve el mismo problema en mi aplicación ASP.Net MVC.
Había dos clases de modelo en mi aplicación que tenían propiedades DateTime.
Al investigar, noté que la propiedad DateTime de un modelo era nulable, es decir, para hacer que la fecha de nacimiento fuera opcional.
el otro modelo tenía DateTime Property con la anotación de datos requeridos (se produce un error al guardar este modelo)
mi aplicación es el código primero, así que resolví el problema estableciendo datatype como DateTime2
[Column(TypeName="datetime2")]
luego ejecuté la migración en la consola del administrador de paquetes.
Tuve el mismo problema y lo [Column(TypeName = "datetime2")]
en propiedades relacionadas, como la muestra siguiente:
[Column(TypeName = "datetime2")]
public DateTime? PropertyName { get; set; }
Tuvimos el mismo problema. Esto estaba relacionado con la versión mssql. Hicimos que funcione en todas nuestras versiones con este método.
Abra su archivo edmx con un editor xml Encuentre esta línea en la parte superior de su archivo
<Schema Namespace="XXXXX.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008"
Reemplace 2008 por 2005 Guarde su archivo, recompile el proyecto.
Espero que eso ayude a alguien más en el futuro.
Solo probé esta solución con un primer enfoque.
Utilice ese script SQL para convertir todas las columnas de datetime a datetime2
. Se salta todas las tablas contiene ''aspnet'' para su conveniencia.
DECLARE @SQL AS NVARCHAR(1024)
DECLARE @TBL AS NVARCHAR(255)
DECLARE @COL AS NVARCHAR(255)
DECLARE @NUL AS BIT
DECLARE CUR CURSOR FAST_FORWARD FOR
SELECT SCHEMA_NAME(t.schema_id)+''.''+t.name, c.name, c.is_nullable
FROM sys.tables AS t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN information_schema.columns i ON i.TABLE_NAME = t.name
AND i.COLUMN_NAME = c.name
WHERE i.data_type = ''datetime'' and t.name not like ''%aspnet%''
ORDER BY t.name, c.name
OPEN CUR
FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SQL = ''ALTER TABLE '' + @TBL
+ '' ALTER COLUMN ['' + @COL + ''] datetime2''
+ (CASE WHEN @NUL=1 THEN '''' ELSE '' NOT'' END) + '' NULL;''
EXEC sp_executesql @SQL
FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL
END
CLOSE CUR;
DEALLOCATE CUR;
¡Esto funciona para mi!