2016-07-15 6 views
1

Ich habe eine DbContext Implementierung (Daten-Repository-Muster), in dem ich das Standardschema zu ändern, wie:EntityFramework Code zuerst mit benutzerdefinierten Standardschema Datenbank Skripterstellung - Referenzen dbo

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.HasDefaultSchema("tm"); 

     base.OnModelCreating(modelBuilder); 
    } 

betreibe ich die folgenden Befehle im Paket-Manager-Konsole, einen sQL-Skript für die Datenbankerstellung zu generieren:

Enable-Migrations -ConnectionStringName "EfDataRepository" 
    Add-Migration Initial -ConnectionStringName "EfDataRepository" 
    Update-Database -ConnectionStringName "EfDataRepository" -Script -SourceMigration:0 

.. was mir das folgende Skript gibt:

DECLARE @CurrentMigration [nvarchar](max) 

IF object_id('[dbo].[__MigrationHistory]') IS NOT NULL 
    SELECT @CurrentMigration = 
     (SELECT TOP (1) 
     [Project1].[MigrationId] AS [MigrationId] 
     FROM (SELECT 
     [Extent1].[MigrationId] AS [MigrationId] 
     FROM [dbo].[__MigrationHistory] AS [Extent1] 
     WHERE [Extent1].[ContextKey] = N'xxxxxxxx' 
     ) AS [Project1] 
     ORDER BY [Project1].[MigrationId] DESC) 

IF object_id('[tm].[__MigrationHistory]') IS NOT NULL 
    SELECT @CurrentMigration = 
     (SELECT TOP (1) 
     [Project1].[MigrationId] AS [MigrationId] 
     FROM (SELECT 
     [Extent1].[MigrationId] AS [MigrationId] 
     FROM [tm].[__MigrationHistory] AS [Extent1] 
     WHERE [Extent1].[ContextKey] = N'xxxxxxxx' 
     ) AS [Project1] 
     ORDER BY [Project1].[MigrationId] DESC) 

IF @CurrentMigration IS NULL 
    SET @CurrentMigration = '0' 

IF @CurrentMigration < '201607151403491_Initial' 
BEGIN 
    IF schema_id('tm') IS NULL 
     EXECUTE('CREATE SCHEMA [tm]') 
    CREATE TABLE [tm].[Settings] (
     [Id] [int] NOT NULL IDENTITY, 
     [Key] [nvarchar](max) NOT NULL, 
     [Value] [nvarchar](max), 
     CONSTRAINT [PK_tm.Settings] PRIMARY KEY ([Id]) 
    ) 

    ... and so on 

Es ist alles gut ... AUSSER, warum generiert es einen Block, der die __MigrationHistory innerhalb des dbo-Schemas prüft?! Und dann geht es richtig weiter, um die __MigrationHistory von meinem benutzerdefinierten Schema zu überprüfen (richtiges Verhalten).

Im Moment lösche ich gerade den dbo verwandten Block, weil ich wirklich mein Schema von jeder Interaktion mit der Standard-isolieren möchte. Wenn ich ein Skript erzeuge, möchte ich nicht, dass es etwas außerhalb des Schemas "tm" tut.

Warum generiert EF das Skript auf diese Weise? Gibt es wirklich einen Grund, die __MigrationHistory aus dem dbo abzufragen, wenn der Rest des Skripts nie etwas dorthin bringt? Versteh ich etwas falsch?

Antwort

1

Es gibt eine Technik zum Verschieben von __MigrationHistory. Diese Tabelle hat einen eigenen Kontext ist (System.Data.Entity.Migrations.History.HistoryContext), die Sie außer Kraft setzen und dann das Schema in OnModelCreating ändern:

public class MyHistoryContext : HistoryContext 
{ 
    public MyHistoryContext(DbConnection dbConnection, string defaultSchema) 
     : base(dbConnection, defaultSchema) 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     modelBuilder.Entity<HistoryRow>().ToTable(tableName: "MigrationHistory", schemaName: "admin"); 
     modelBuilder.Entity<HistoryRow>().Property(p => p.MigrationId).HasColumnName("Migration_ID"); 
    } 
} 

Dann müssen Sie es register:

public class ModelConfiguration : DbConfiguration 
{ 
    public ModelConfiguration() 
    { 
     this.SetHistoryContext("System.Data.SqlClient", 
      (connection, defaultSchema) => new MyHistoryContext(connection, defaultSchema)); 
    } 
} 
+0

Es kann einen eigenen Kontext haben, aber die Tabelle __MigrationHistory gehört immer noch zu einem Schema. Es sollte zu meinem Schema gehören. Warum leckt es außerhalb meines Schemas zum 'dbo'? Wenn es nur die _MH-Tabelle in der 'dbo' manipulieren würde, würde ich verstehen - aber was mich wirklich verwirrt, ist der doppelte Block für _MH - einmal in meinem Schema und einmal in der dbo. Ich kann meine Hand nicht darum wickeln. –

+0

Es ist definitiv fehlerhaft mit der Schema-Handhabung - wir haben es mehrmals gehackt, um es so zu bekommen, wie wir es brauchen. –

+0

Dank @Steve Greene, ich denke auch, dass es ein Fehler ist. Ich habe es gemeldet. –

0

Ich habe protokolliert dies als issue on the EF codeplex project page. Sie haben das Problem mit der folgenden Erklärung geschlossen:

Es ist für eine frühere Version der Geschichte Tabelle sucht, kann im dbo-Schema gewesen sind, ist dies durch Design-Unterstützung zu helfen es bewegen.

Verwandte Themen