实体框架4.3.1代码优先:创建数据库但不创建表

Cod*_*ber 8 sql-server-ce entity-framework-4 ef-code-first ef-migrations

今天我将旧的应用程序从EF 4.2迁移到EF 4.3.1.在我的应用程序中,我使用CodeFirst,但在迁移后它停止工作,并找不到原因.为了清除任何其他可能的问题,我决定创建一个小型控制台应用程序,并使用ADO团队发布的数据迁移演练:

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 Compact,但结果相同(不同的错误):

  • 只创建了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');
Run Code Online (Sandbox Code Playgroud)

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

这是一个错误还是什么?它始终与其他日期时间一起使用.

更新 我尝试将其作为显式迁移运行,并使用-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 ]
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢西蒙娜

Cod*_*ber 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) + "'";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在Configuration类中指定新的SqlGenerator:

SetSqlGenerator("System.Data.SqlClient", new FixedSqlGenerator());
Run Code Online (Sandbox Code Playgroud)

如果只想在手动迁移中使用它,如果只需要CodeFirst,则必须在应用程序启动代码或DbContext中指定配置.

Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Migrations.Configuration>());
Run Code Online (Sandbox Code Playgroud)

HTH