8

Dziś migrowałem starą aplikację z EF 4.2 do EF 4.3.1. W mojej aplikacji korzystałem z CodeFirst, ale po migracji przestało działać i nie mogłem znaleźć przyczyny. Aby usunąć dowolny inny możliwy problem postanowiłem stworzyć małą aplikację konsoli i użyłem Migracja danych walk-through opublikowany przez zespół ADO:Entity Framework 4.3.1 Code First: baza danych utworzona, ale tabele nie są

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

skopiowałem dokładnie kod bloga, ale zamiast z działa poprawnie (tworzenie DB, tworzenie schematu i wstawienie blog) mam pewne błędy:

  • tylko zostanie utworzony DB, ale nie tabele
  • otrzymuję ten błąd Conversion failed when converting datetime from character string. "

Wszystko to w Express Express programu SQL Server 2005.

Próbowałem sam pomocą SQL Compact, ale sam wynik (tho innego błędu):

  • tylko utworzeniu DB (w tym przypadku do pliku SDF w folderze bin), ale bez tabel
  • pojawia się błąd The format of the specified date or time datepart is not valid. [ String = 2012-04-19T13.21.04.364 ]

myślę, że w obu przypadkach problem tkwi w tym, że linia EF chce wejść jako pierwszy migracji:

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

Podobno format z. jest źle, przynajmniej w moim języku, powinno być z:

Czy to błąd? Zawsze działało z innymi datetime wcześniej.

UPDATE Próbowałem uruchomić go jako wyraźnej migracji i stosowania migrację z -verbose flagą, a tutaj jest to, co mam:

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 ] 

Aktualizacja 2 mam zainstalowany SQL Server Profiler i profilowane, co się tam dzieje. Wykonałem wszystkie instrukcje jeden po drugim za pomocą analizatora zapytań, a ten, który zawodził, jest, jak już wspomniano powyżej, wstawieniem migracji.

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

Przy zmianie formatu ciąg DATATIME z 2012-04-23T14.16.59.038Z do 2012-04-23T14:16:59.038Z polecenie przeszedł, więc myślę, że jakoś EF wysyła DATATIME w formacie, który nie jest zgodny z moim lokalizacji.

Dziękuję Simone

+0

Hi Simone, co jest ustawienia narodowe maszyny db i sortowanie bazy danych? Dziwne, że T-SQL działa dobrze przez SSMS, chociaż maszyna –

+0

DB (moja maszyna) jest to-IT, zestawienie DB jest francuskim, co może wyjaśniać w SQL Express (nawet jeśli 2012-04-19T13.21.04.364 powinno być niezmienny format). Ale SQL Compact działa w tym samym kontekście aplikacji, co nie powinno być problemem. – CodeClimber

+0

@CodeClimber http://stackoverflow.com/a/9745125/417747 - zobacz, czy to łącze pomaga (mój post na moim komputerze w podobnym temacie, po tych kilku rzeczach powinien ci pomóc, z mojego doświadczenia wynikającego głównie z migracji, inicjalizatory i ewentualnie ciąg połączenia) - daj mi znać, a ja postaram się bardziej szczegółowo odpowiedzieć. – NSGaga

Odpowiedz

7

Dzięki Zespołu ADO.NET, że był to błąd w kodzie migracji. Najwyraźniej zapomnieli oni ustawić InvariantCulture, gdy generują kod dla pola DateTime, więc działa on w ustawieniach regionalnych EN, ale nie w innych ustawieniach regionalnych.

Aby rozwiązać ten problem, czekając na oficjalne poprawki należy określić niestandardową SqlGenerator że przesłania metodę Generate(DateTime defaultValue):

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

a następnie określ nową SqlGenerator w klasie konfiguracji:

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

Jeśli chcesz go użyć tylko w ręcznych migracjach, jeśli potrzebujesz tylko CodeFirst, musisz określić konfigurację w kodzie startowym aplikacji lub w DbContext.

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

HTH

0

miałem ten sam problem z nowym projektem, w moim przypadku mogę rozwiązać go poprzez określenie właściwej kultury w moim web.config

<globalization enableClientBasedCulture="false" culture="en-US" /> 
Powiązane problemy