8

Hoy he migrado una aplicación anterior de EF 4.2 a EF 4.3.1. En mi aplicación estaba usando CodeFirst, pero después de la migración dejó de funcionar y no pudo encontrar una razón para eso. Para despejar cualquier otro posible problema que decidí crear una pequeña aplicación de consola y he utilizado la migración de datos a pie-a través publicada por el equipo de ADO:Entity Framework 4.3.1 Código Primero: base de datos creada pero las tablas no son

http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx

que copia exactamente el código del blog, pero en su lugar de trabajar correctamente (la creación de la base de datos, crear el esquema, e insertando el blog) consigo algunos errores:

  • sólo se crea la base de datos, pero no hay mesas
  • consigo este error Conversion failed when converting datetime from character string. "

Todo esto en SQL Server 2005 express.

me trataron de la misma utilizando SQL compacto, pero el mismo resultado (aunque diferente de error):

  • sólo se crea la base de datos (en este caso un archivo SDF en la carpeta bin), pero no hay mesas
  • me sale el error The format of the specified date or time datepart is not valid. [ String = 2012-04-19T13.21.04.364 ]

creo que en ambos casos el problema radica en que la línea EF quiere entrar como primera migración:

INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) 
VALUES ('201204191321184_init', '2012-04-19T13.21.04.364', ...., '4.3.1'); 

Aparentemente el formato con. es incorrecto, al menos en mi configuración regional, debería ser con:

¿Esto es un error o qué? Siempre funcionó con otro datetime antes.

ACTUALIZACIÓN Intenté funcionar como la migración explícita, y la aplicación de la migración con el indicador -verbose, y esto es lo que me sale:

PM> Update-Database -Verbose 
Using NuGet project 'ConsoleApplication2'. 
Using StartUp project 'ConsoleApplication2'. 
Target database is: '|DataDirectory|ConsoleApplication2.ConsoleApplication1.BlogContext.sdf' (DataSource: |DataDirectory|ConsoleApplication2.ConsoleApplication1.BlogContext.sdf, Provider: System.Data.SqlServerCe.4.0, Origin: Convention). 
Applying explicit migrations: [201204191356197_Initial]. 
Applying explicit migration: 201204191356197_Initial. 
CREATE TABLE [Blogs] (
    [BlogId] [int] NOT NULL IDENTITY, 
    [Name] [nvarchar](4000), 
    CONSTRAINT [PK_Blogs] PRIMARY KEY ([BlogId]) 
) 
CREATE TABLE [__MigrationHistory] (
    [MigrationId] [nvarchar](255) NOT NULL, 
    [CreatedOn] [datetime] NOT NULL, 
    [Model] [image] NOT NULL, 
    [ProductVersion] [nvarchar](32) NOT NULL, 
    CONSTRAINT [PK___MigrationHistory] PRIMARY KEY ([MigrationId]) 
) 
[Inserting migration history record] 
System.Data.SqlServerCe.SqlCeException (0x80004005): The format of the specified date or time datepart is not valid. [ String = 2012-04-19T13.56.45.437 ] 
    at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr) 
    at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommandText(IntPtr& pCursor, Boolean& isBaseTableCursor) 
    at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options) 
    at System.Data.SqlServerCe.SqlCeCommand.ExecuteNonQuery() 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements) 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading) 
    at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 
    at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
    at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore() 
    at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run() 
The format of the specified date or time datepart is not valid. [ String = 2012-04-19T13.56.45.437 ] 

Actualización 2 he instalado SQL Server Profiler, y describió lo que está pasando allí. He ejecutado todas las declaraciones una por una a través del analizador de consultas y la que falla es, como ya se indicó anteriormente, la inserción de la migración.

INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) VALUES ('201204231416585_InitialCreate', '2012-04-23T14.16.59.038Z', ...., '4.3.1') 

Al cambiar el formato de la cadena DataTime 2012-04-23T14.16.59.038Z-2012-04-23T14:16:59.038Z el comando tuvo que pasar, así que supongo que de alguna manera EF está enviando el DataTime en el formato que no es compatible con mi configuración regional.

Gracias Simone

+0

Hola Simone, ¿cuál es la localización de la máquina db y recopilación de la base de datos? Es extraño que el T-SQL funcione bien a través de SSMS aunque –

+0

máquina de base de datos (mi máquina) es it-IT, la intercalación de DB es francesa, eso podría explicar en SQL Express (incluso si 2012-04-19T13.21.04.364 debería ser el formato invariante). Pero SQL Compact se ejecuta en el mismo contexto de la aplicación, ese no debería ser el problema. – CodeClimber

+0

@CodeClimber http://stackoverflow.com/a/9745125/417747 - mira si este enlace ayuda (otro post mío sobre un problema similar, siguiendo esas pocas cosas debería ayudarte a obtenerlo, en mi experiencia, que se trata principalmente de migraciones, inicializadores y posiblemente cadena de conexión) - hágamelo saber y publicaré una respuesta más completa. – NSGaga

Respuesta

7

gracias al equipo de ADO.NET, se trataba de un error en el código de migración. Aparentemente olvidaron especificar InvariantCulture cuando generan código para un campo DateTime, por lo que funciona en la configuración regional EN, pero no en otras configuraciones regionales.

Para solucionar este problema, a la espera de una solución oficial, se debe especificar un SqlGenerator personalizada que anula el Generate(DateTime defaultValue) método:

class FixedSqlGenerator : SqlServerMigrationSqlGenerator 
{ 
    protected override string Generate(DateTime defaultValue) 
    { 
     return "'" + defaultValue.ToString("yyyy-MM-ddTHH:mm:ss.fffK", CultureInfo.InvariantCulture) + "'"; 
    } 
} 

Y a continuación, especifique la nueva SqlGenerator en la clase de configuración:

SetSqlGenerator("System.Data.SqlClient", new FixedSqlGenerator()); 

Si desea usarlo solo en migraciones manuales, si solo necesita CodeFirst, debe especificar la configuración en el código de inicio de la aplicación o en el DbContext.

Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Migrations.Configuration>()); 

HTH

0

he tenido el mismo problema con un nuevo proyecto, en mi caso resuelto mediante la especificación de la cultura adecuada en mi web.config

<globalization enableClientBasedCulture="false" culture="en-US" /> 
Cuestiones relacionadas