简体   繁体   English

实体框架代码首先没有app.config

[英]Entity Framework Code First without app.config

I hope somebody is able to help me, because it seems I'm totally stuck. 我希望有人能够帮助我,因为我似乎完全陷入困境。

For upcoming projects in our company we'd like to use Entity Framework 5 with an code first approach. 对于我们公司即将开展的项目,我们希望使用Entity Framework 5和代码优先方法。 I played around a little while and everytime I try to use EF with our existing libraries, I fail because it seems EF heavily relies on an existing app.config. 我玩了一会儿,每当我尝试在我们现有的库中使用EF时,我都失败了,因为看起来EF很大程度上依赖于现有的app.config。

In our company, we have an inhouse database library that allows us to connect to various data sources and database technologies taking the advantages of MEF (managed extensibility framework) for database providers. 在我们公司,我们有一个内部数据库库,允许我们利用MEF(托管扩展性框架)的优势连接到各种数据源和数据库技术,用于数据库提供者。 I just have to pass some database settings, such as host (or file), catalog, user credentials and a database provider name, the library looks for the appropriate plugin and returns me a custom connection string or IDbConnection. 我只需要传递一些数据库设置,例如主机(或文件),目录,用户凭据和数据库提供程序名称,库会查找相应的插件并返回自定义连接字符串或IDbConnection。 We'd like to use this library together with EF because it allows us to be flexible about which database we use also change the database at runtime. 我们希望将此库与EF一起使用,因为它允许我们灵活地使用我们使用的数据库,并在运行时更改数据库。

So. 所以。 I saw that a typical DbContext object takes no parameters in the constructor. 我看到一个典型的DbContext对象在构造函数中没有参数。 It automatically looks for the appropriate connection string in app.config. 它会自动在app.config中查找相应的连接字符串。 We don't like such things so I changed the default constructor to take a DbConnection object that get's passed to the DbContext base class. 我们不喜欢这样的东西所以我改变了默认构造函数来获取一个DbConnection对象,该对象被传递给DbContext基类。 No deal. 没有成交。

Problems occur when the code first model changes. 代码第一个模型更改时出现问题。 EF automatically notices this and looks for migration classes / configuration. EF会自动注意到这一点并查找迁移类/配置。 But: A typical migration class requires a default parameterless constructor for the context! 但是:典型的迁移类需要上下文的默认无参数构造函数! What a pity! 太遗憾了!

So we build our own migration class using the IDbContextFactory interface. 因此,我们使用IDbContextFactory接口构建自己的迁移类。 But again, it seems that also this IDbContextFactory needs a parameterless constructor, otherwise I'm not able to add migrations or update the database. 但同样,似乎这个IDbContextFactory也需要一个无参数构造函数,否则我无法添加迁移或更新数据库。

Further, I made my own data migration configurator where I pass the context, also the target database. 此外,我创建了自己的数据迁移配置程序,我传递了上下文,也是目标数据库。 Problem is here: It doesn't find any migration classes, no matter what I try. 问题在于:无论我尝试什么,它都找不到任何迁移类。

I'm completely stuck because it seems the only way to use EF is when connection strings are saved in app.config. 我完全陷入困境,因为似乎使用EF的唯一方法是在app.config中保存连接字符串。 And this is stupid because we need to change database connections at runtime, and app.config is read-only for default users! 这是愚蠢的,因为我们需要在运行时更改数据库连接,app.config对于默认用户是只读的!

How to solve this? 怎么解决这个?

The answer is provided here 答案在这里提供

https://stackoverflow.com/a/15919627/941240 https://stackoverflow.com/a/15919627/941240

The trick is to slightly modify the default MigrateDatabaseToLatestVersion initializer so that: 诀窍是稍微修改默认的MigrateDatabaseToLatestVersion初始化程序,以便:

  • the database is always initialized ... 数据库总是初始化...
  • ... using the connection string from current context ...使用当前上下文中的连接字符串

The DbMigrator will still create a new data context but will copy the connection string from yours context according to the initializer. DbMigrator仍将创建新的数据上下文,但会根据初始化程序从您的上下文中复制连接字符串。 I was even able to shorten the code. 我甚至能够缩短代码。

And here it goes: 它在这里:

public class MasterDetailContext : DbContext
{
    public DbSet<Detail> Detail { get; set; }
    public DbSet<Master> Master { get; set; }

    // this one is used by DbMigrator - I am NOT going to use it in my code
    public MasterDetailContext()
    {
        Database.Initialize( true );
    }

    // rather - I am going to use this, I want dynamic connection strings
    public MasterDetailContext( string ConnectionString ) : base( ConnectionString )
    {
        Database.SetInitializer( new CustomInitializer() );
        Database.Initialize( true );
    }

    protected override void  OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

public class CustomInitializer : IDatabaseInitializer<MasterDetailContext>
{

    #region IDatabaseInitializer<MasterDetailContext> Members

    // fix the problem with MigrateDatabaseToLatestVersion 
    // by copying the connection string FROM the context
    public void InitializeDatabase( MasterDetailContext context )
    {            
        Configuration cfg = new Configuration(); // migration configuration class
        cfg.TargetDatabase = new DbConnectionInfo( context.Database.Connection.ConnectionString, "System.Data.SqlClient" );

        DbMigrator dbMigrator = new DbMigrator( cfg );
        // this will call the parameterless constructor of the datacontext
        // but the connection string from above will be then set on in
        dbMigrator.Update();             
    }

    #endregion
}

Client code: 客户代码:

    static void Main( string[] args )
    {

        using ( MasterDetailContext ctx = new MasterDetailContext( @"Database=ConsoleApplication801;Server=.\SQL2012;Integrated Security=true" ) )
        {
        }

        using ( MasterDetailContext ctx = new MasterDetailContext( @"Database=ConsoleApplication802;Server=.\SQL2012;Integrated Security=true" ) )
        {
        }
    }

Running this will cause the two databases to be created and migrated according to the migration configuration. 运行此命令将导致根据迁移配置创建和迁移两个数据库。

It needs a parameterless constructor in order to invoke it. 它需要一个无参数构造函数才能调用它。 What you could do is provide your default DbConntectionFactory in the empty constructor, something like: 你可以做的是在空构造函数中提供默认的DbConntectionFactory ,如:

public DbContext()
{
    IDbContextFactory defaultFactory; //initialize your default here
    DbContext(defaultFactory);
}

public DbContext(IDbContextFactory factory)
{
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 没有App.config的SQLite实体框架 - SQLite Entity Framework without App.config 不带App.config的实体框架,数据库优先,存储库模式,N层解决方案体系结构 - Entity Framework without App.config, Database first, Repository Pattern, N-tier Solution Architecture 实体框架(代码优先到现有数据库)-在运行时覆盖app.config中的连接字符串 - Entity Framework(Code First to an existing database) - overwrite a connection string in app.config at runtime 未创建实体框架 6 App.config 文件 - Entity Framework 6 App.config file is not created App.Config中的实体框架连接字符串 - Entity Framework Connection String in App.Config app.config和用于远程连接的实体框架 - app.config and Entity Framework for remote connection 将实体框架与 Sql 服务器精简版一起使用,无需添加 App.Config - Using Entity Framework with Sql Server Compact Edition without App.Config additions App.Config PostgreSQL实体框架6的Npgsql C#问题 - Npgsql C# problem with App.Config PostgreSQL Entity Framework 6 实体框架未在app.config中使用连接字符串 - Entity Framework not using connection string in app.config 在 app.config 之外的实体框架中为 PostgreSQL 数据库设置 connectionString - Set a connectionString for a PostgreSQL database in Entity Framework outside the app.config
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM