EntityFramework代码优先于自定义默认架构数据库脚本生成 - 引用dbo

时间:2016-07-15 14:11:13

标签: entity-framework ef-code-first

我有一个DbContext实现(数据存储库模式),我在其中更改了默认模式,如下所示:

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

        base.OnModelCreating(modelBuilder);
    }

我在程序包管理器控制台中运行以下命令,以生成用于创建数据库的.sql脚本:

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

..它给了我以下脚本:

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

一切都很好......除了为什么会生成一个块,它会检查dbo架构中的__MigrationHistory ?!然后它正确地从我的自定义架构中检查__MigrationHistory(正确的行为)。

目前,我只是删除了dbo相关的块,因为我真的想要将我的架构与默认架构的任何交互隔离开来。当我生成一个脚本时,我不希望它在'tm'模式之外做任何事情。

为什么EF会以这种方式生成脚本?是否有任何理由从dbo中查询__MigrationHistory,当脚本的其余部分从未放入任何内容时?我误解了什么吗?

2 个答案:

答案 0 :(得分:1)

有一种移动__MigrationHistory的技术。该表具有自己的上下文(System.Data.Entity.Migrations.History.HistoryContext),您可以覆盖它,然后在OnModelCreating中更改架构:

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

然后你需要register它:

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

答案 1 :(得分:0)

我已将其记录为issue on the EF codeplex project page。他们通过以下解释结束了这个问题:

  

它正在寻找可能的历史表的先前版本   已经在dbo架构中,这是设计帮助支持移动   它