8

今天,我将旧应用程序从EF 4.2迁移到EF 4.3.1。 在我的应用程序中,我使用的是CodeFirst,但在迁移后它停止工作,并且找不到原因。 要清除任何其他可能出现的问题,我决定创建一个小型控制台应用程序,我使用了数据迁移步行通过由ADO队公布:实体框架4.3.1代码优先:创建数据库但表格不是

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

我复制博客的完全代码,而是工作正常(创建数据库,创建模式,并插入博客)我得到了一些错误:

  • 只有DB被创建,但没有表
  • 我得到这个错误Conversion failed when converting datetime from character string.

所有这些都在SQL Server 2005 express上。

我尝试同样使用SQL精简,但相同的结果(寿不同的错误):

  • 只有DB创建(在这种情况下的bin文件夹中的SDF文件),但没有表
  • 我得到的错误The format of the specified date or time datepart is not valid. [ String = 2012-04-19T13.21.04.364 ]

我认为在这两种情况下,问题在于,EF想作为第一迁移进入行:

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

显然与格式。是错误的,至少在我的语言环境中,它应该与:

这是一个错误还是什么?它以前一直与其他日期时间一起工作。

UPDATE 我试图运行它作为明确的迁移,并与-verbose标志设置应用迁移,这里是我所得到的:

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 ] 

更新2 我安装了SQL Server Profiler,并描述了那里发生的事情。 我通过查询分析器逐个执行所有的语句,失败的语句如上所述,插入了迁移。

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

当改变DATATIME字符串从2012-04-23T14.16.59.038Z的格式2012-04-23T14:16:59.038Z命令经历了,所以我想以某种方式EF被发送格式的DATATIME,是不是我的语言环境兼容。

谢谢 西蒙娜

+0

西蒙娜嗨指定正确的文化,有什么数据库机器的语言环境和数据库的排序规则?奇怪的是,T-SQL通过SSMS运行良好,尽管 – 2012-04-19 13:36:42

+0

DB机器(我的机器)是IT-IT,数据库的排序规则是法语,可以在SQL Express上解释(即使2012-04-19T13.21.04.364应该是不变的格式)。但是SQL Compact运行在应用程序的相同上下文中,这应该不是问题。 – CodeClimber 2012-04-19 13:46:05

+0

@CodeClimber http://stackoverflow.com/a/9745125/417747 - 看看这个链接是否有帮助(在我遇到类似问题的帖子后,下面这几件事可以帮助你获得答案,根据我的经验,主要是围绕迁移,初始化器和可能的连接字符串) - 让我知道,我会发布更彻底的答案。 – NSGaga 2012-04-19 13:54:24

回答

7

由于ADO.NET团队,这是在迁移代码中的错误。 显然,当他们为DateTime字段生成代码时,他们忘记指定InvariantCulture,因此它在EN语言环境中工作,但不在其他语言环境中工作。

要解决此问题,等待官方补丁,你应该指定覆盖Generate(DateTime defaultValue)方法自定义SqlGenerator:

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

,然后指定在配置类新SqlGenerator:

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

如果您只是在手动迁移时使用它,那么如果您只需要CodeFirst,则必须在应用程序启动代码或DbContext中指定配置。

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

HTH

0

我有一个全新的项目,同样的问题,在我的情况我解决它在我的web.config

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