8

今日、古いアプリケーションを 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 の作成、スキーマの作成、およびブログの挿入)、いくつかのエラーが発生します。

  • 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');

どうやら . 少なくとも私のロケールでは、次のようにする必要があります。

これはバグですか?以前は常に他の日時で機能していました。

更新 明示的な移行として実行し、-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 ]

Update 2 SQL Server Profiler をインストールし、そこで何が起こっているかをプロファイリングしました。クエリ アナライザーを使用してすべてのステートメントを 1 つずつ実行しましたが、失敗したのは、既に述べたように、移行の挿入です。

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 を送信していると思います。

ありがとうシモーネ

4

2 に答える 2

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) + "'";
    }
}

次に、Configuration クラスで新しい SqlGenerator を指定します。

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

手動移行でのみ使用する場合は十分です。CodeFirst のみが必要な場合は、アプリケーションのスタートアップ コードまたは DbContext で構成を指定する必要があります。

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

HTH

于 2012-04-30T09:53:15.123 に答える
0

私はまったく新しいプロジェクトで同じ問題を抱えていました。私の場合、web.configで適切なカルチャを指定することで解決しました

<globalization enableClientBasedCulture="false" culture="en-US" />
于 2012-07-12T15:27:00.963 に答える