簡體   English   中英

EF代碼優先:繼承的dbcontext創建兩個數據庫

[英]EF code first: inherited dbcontext creates two databases

我正在嘗試創建一個基本dbcontext,其中包含所有常用實體,這些實體將始終在多個項目中重用,如頁面,用戶,角色,導航等。

這樣做我有一個ContextBase類繼承DbContext並定義我想要的所有DbSet。 然后我有一個Context類繼承ContextBase,我定義項目特定的DbSet。 這些類定義如下:

public class ContextBase : DbContext
{
    public virtual DbSet<User> Users { get; set; }
    //more sets

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new UsersConfiguration());
        //add more configurations
    }
}


public class Context : ContextBase
{
    public DbSet<Building> Buildings { get; set; }
    //some more project specific sets

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new BuildingsConfiguration());
        //add more project specific configs
    }
}

在我的global.asax中:

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

其中Configuration引用繼承DbMigrationsConfiguration並重寫Seed方法的類。

兩個上下文類在同一名稱空間中定義,但是交叉程序集(為了我可以在多個現有項目中更新基礎項目而不觸及項目特定代碼) - 不確定這是否相關。

我的問題:運行此代碼時,它工作正常,但在查看數據庫時,它實際上創建了兩個不同的數據庫! 一個包含所有基本實體表,另一個包含BOTH基表和自定義表。 CRUD操作只在自定義版本上執行(這顯然是我想要的),但為什么它也會創建另一個版本的模式?

任何幫助表示贊賞,謝謝!

更新:

以下代碼是我最終得到的。 它並不理想,但它確實有效。 我仍然希望獲得有關如何改進這一點的反饋,但與此同時,我希望這有助於推動這一進程。 我真的不推薦這樣做! 它非常容易出錯並且非常令人沮喪。 我只是發布這個,看看是否有更好的想法或實現來實現這一目標。

仍然存在的一個(但不是唯一的)問題是必須手動將MVC視圖添加到項目中。 我已經將它添加到Nuget包中,但是當VS連接到TFS時,需要2到3個小時來應用具有如此多文件的nuget包。 通過一些更多工作和自定義View引擎,可以預編譯視圖( http://blog.davidebbo.com/2011/06/precompile-your-mvc-views-using.html )。

該解決方案分為Base Framework項目和Custom項目(每個類別包括自己的模型和存儲庫模式)。 框架項目打包在Nuget包中,然后安裝在任何自定義項目中,允許任何項目的常用功能,如用戶,角色和權限管理,內容管理等(通常稱為Boiler Plate)輕松添加到任何新項目。 這允許在任何現有的自定義項目中遷移樣板的任何改進。

定制數據庫初始化器:

public class MyMigrateDatabaseToLatestVersion : IDatabaseInitializer<Context>
{
    public void InitializeDatabase(Context context)
    {
        //create the base migrator
        var baseConfig = new FrameworkConfiguration();
        var migratorBase = new DbMigrator(baseConfig);
        //create the custom migrator
        var customConfig = new Configuration();
        var migratorCustom = new DbMigrator(customConfig);

        //now I need to check what migrations have not yet been applied
        //and then run them in the correct order
        if (migratorBase.GetPendingMigrations().Count() > 0)
        {
            try
            {
                migratorBase.Update();
            }
            catch (System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException)
            {
                //if an error occured, the seed would not have run, so we run it again.
                baseConfig.RunSeed(context);
            }
        }
        if (migratorCustom.GetPendingMigrations().Count() > 0)
        {
            try
            {
                migratorCustom.Update();
            }
            catch (System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException)
            {
                //if an error occured, the seed would not have run, so we run it again.
                customConfig.RunSeed(context);
            }
        }
    }
}

Framework的數據庫遷移配置:

public class FrameworkConfiguration: DbMigrationsConfiguration<Repository.ContextBase>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    public void RunSeed(Repository.ContextBase context)
    {
        Seed(context);
    }

    protected override void Seed(Repository.ContextBase context)
    {
        //  This method will be called at every app start so it should use the AddOrUpdate method rather than just Add.

        FrameworkDatabaseSeed.Seed(context);
    }
}

Custom Project的數據庫遷移配置:

public class Configuration : DbMigrationsConfiguration<Repository.Context>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    public void RunSeed(Repository.Context context)
    {
        Seed(context);
    }

    protected override void Seed(Repository.Context context)
    {
        //  This method will be called at every app start so it should use the AddOrUpdate method rather than just Add.

        CustomDatabaseSeed.Seed(context);
    }
}

自定義DbContext

//nothing special here, simply inherit ContextBase, IContext interface is purely for DI
public class Context : ContextBase, IContext
{
    //Add the custom DBsets, i.e.
    public DbSet<Chart> Charts { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Assign the model configs, i.e.
        modelBuilder.Configurations.Add(new ChartConfiguration());
    }
}

框架DbContext:

//again nothing special
public class ContextBase: DbContext
{
    //example DbSet's
    public virtual DbSet<Models.User> Users { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder);
}

在global.asax AppStart中:

        //first remove the base context initialiser
        Database.SetInitializer<ContextBase>(null);
        //set the inherited context initializer
        Database.SetInitializer(new MyMigrateDatabaseToLatestVersion());

在web.config中:

<connectionStrings>
    <!--put the exact same connection string twice here and name it the same as the base and overridden context. That way they point to the same database. -->
    <add name="Context" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=CMS2013; Integrated Security=SSPI;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient"/>
    <add name="ContextBase" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=CMS2013; Integrated Security=SSPI;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient"/>
</connectionStrings>

(來自評論)

您正在直接創建ContextBase對象,顯然是在使用ContextBase作為泛型類型參數的泛型方法中的new T() ,因此ContextBase任何初始化程序也會運行。 要防止創建ContextBase對象(如果永遠不應該直接實例化,如果應始終使用派生的上下文),則可以將該類標記為abstract

你的ContextBase似乎也有一個初始化器。你可以刪除它

Database.SetInitializer<ContextBase>(null);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM