renathy
renathy

Reputation: 5355

DbContext and database initalizer in Entity Framework 6

Where is the proper place to call

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

Below is description of architecture for my project.

I have MVC + webAPI project, where Data Access Layer is seperate project and it uses Entity Framework 6.1.3. I have defined class MyDbContext:

public class EedezDbContext : System.Data.Entity.DbContext

I have also Configuration class with Seed method.

    internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
    {            
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(Eedez.Dal.DbContext.EedezDbContext context)
        {
            // running seeds
        }
    }

DataAccessLayer also has DataAccessors that calls entity framework methods to make operations with data. Each method of dataaccessor creates instance of MyDbContext. For instance, here is one base accessor method:

 public class AccessorBase<T> : IAccessorBase<T> where T : BaseEntity
    {
       public virtual IEnumerable<T> GetByFilter(Expression<Func<T, bool>> filter)
        {
            using (MyDbContext context = new MyDbContext())
            {
                return IncludeRefObjects(context.Set<T>()).Where(filter).ToList();
            }
        }     
...
}

I am not sure where to add database initializer. Most of the examples I have found add database initializer into global.asax, but this is not my case, because Data Access Layer is in separate project. To run project for now, I haved add initalizer here:

public class MyDbContext : System.Data.Entity.DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Company> Companies { get; set; }
    ...

    public MyDbContext()
        : base("MyDb")
    {
        var type = typeof(System.Data.Entity.SqlServer.SqlProviderServices);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Configurations.Add(new CompanyConfig());
        modelBuilder.Configurations.Add(new UserConfig());
        ...

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

Is this the right place?

Upvotes: 1

Views: 1037

Answers (2)

Jose Rodriguez
Jose Rodriguez

Reputation: 10192

I usually prefer to configure the initializer database within EntityFramework configuration section on web.config file, for example:

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <contexts>
      <context type="MyAssembly.Fullname.EedezDbContext, MyAssembly.Fullname">
        <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[MyAssembly.Fullname.EedezDbContext, MyAssembly.Fullname], [MyAssembly.Fullname.Configuration, MyAssembly.Fullname ]], EntityFramework" />
      </context>
    </contexts>
</entityFramework>

If you find it very difficult to write the full assembly qualified name type, just you can use this code to get it:

var configInitializer =  typeof (MigrateDatabaseToLatestVersion<EedezDbContext, Configuration>).AssemblyQualifiedName;

and paste this value on type property of databaseInitializer element.

Upvotes: 0

Sam FarajpourGhamari
Sam FarajpourGhamari

Reputation: 14741

Set in your DbContexts static constructor. This method just calls one time and automatically just before you first time use your class.

public class MyDbContext : System.Data.Entity.DbContext
{
    static MyDbContext()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>());
    }

    // your other code
    public MyDbContext()
    : base("MyDb")
    {
        var type = typeof(System.Data.Entity.SqlServer.SqlProviderServices);
    }
    // ..
}

Upvotes: 2

Related Questions