David Létourneau
David Létourneau

Reputation: 1250

How reuse an existing DbContext as base class for a new project?

I have an existing DbContext class that I want to use as a base class for my other web projects. That DbContext contain a really complete table structure to registrer companies and peoples with related information’s.

When starting a new project, I do not want to create the same structure again and again! So I try to reuse the existing DbContext as a base class for my new project and just adding the new tables needed to make it working as wanted in the new application.

But, I cannot find a way to make it working! The DbContext base class is like below, it came from another project:

public class TemplateDbContext 
{       
        private readonly Guid _instanceId;
        bool _disposed;
        public Guid InstanceId { get { return _instanceId; } }
        public TemplateDbContext ()
            : base("name=" + GetConnectionStringName)
        {
        }

        public static TemplateDbContext  Create() 
        {
            return new TemplateDbContext ();
        }
        private void SetOneToMany(DbModelBuilder modelBuilder)
        {

        }

        private void SetManyToMany(DbModelBuilder modelBuilder)
        {

        }

        private void SetOneToOne(DbModelBuilder modelBuilder)
        {

        }

        private void SetOneNavigation(DbModelBuilder modelBuilder)
        {

        }

        private void SetKeys(DbModelBuilder modelBuilder)
        {

        }

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

            modelBuilder.Entity<IdentityUserClaim>().ToTable("MembershipClaims");
            modelBuilder.Entity<IdentityUserRole>().ToTable("MembershipRoles");
            modelBuilder.Entity<IdentityUserLogin>().ToTable("MembershipLogins");
            modelBuilder.Entity<IdentityRole>().ToTable("Roles");
            modelBuilder.Entity<Membership>().ToTable("Memberships");

            SetKeys(modelBuilder);
            SetOneNavigation(modelBuilder);
            SetOneToOne(modelBuilder);
            SetOneToMany(modelBuilder);
            SetManyToMany(modelBuilder);
        }

        public static string GetConnectionStringName
        {
            get
            {
                ...
            }
        }

        public DbSet<UserProfile> UserProfiles
        {
            get;
            set;
        }

        // I have many more DbSet defined here...
        public override int SaveChanges()
        {
            ...
        }

        public override async Task<int> SaveChangesAsync()
        {
            ...
        }

        public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
        {
            ...
        }

        public void SyncObjectState<TEntity>(TEntity entity) where TEntity : class, IObjectState
        {
            ...
        }

        private void SyncObjectsStatePreCommit()
        {
            ...
        }

        public void SyncObjectsStatePostCommit()
        {
            ...
        }

        protected override void Dispose(bool disposing)
        {
            ...
        }
}

Here is the ApplicationDbContext for my new project :

public class ApplicationDbContext : TemplateDbContext 
    {
        public DbSet<Fruit> Fruits { get; set; }
        // I have many more DbSet define here...

        private void SetOneToMany(DbModelBuilder modelBuilder)
        {
           ...
        }

        private void SetManyToMany(DbModelBuilder modelBuilder)
        {
           ...
        }

        private void SetOneToOne(DbModelBuilder modelBuilder)
        {
            ...
        }

        private void SetOneNavigation(DbModelBuilder modelBuilder)
        {
           ...
        }

        private void SetKeys(DbModelBuilder modelBuilder)
        {
            ...
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            SetKeys(modelBuilder);
            SetOneNavigation(modelBuilder);
            SetOneToOne(modelBuilder);
            SetOneToMany(modelBuilder);
            SetManyToMany(modelBuilder);
        }
    }

As you could guest, this is not working at all and I don’t know how I can achieve the result I want. I even don’t know if it is possible without duplicating all the code from TemplateDbContext class. The best things that I accomplished for now, it to generate the TemplateDbContext only, by executed the Add-Migration with Package Manager Console within the new project. So the migration missed all the DbSet defined into the ApplicationDbContext class.

What kind of structure I need to do that?

Upvotes: 1

Views: 801

Answers (1)

adricadar
adricadar

Reputation: 10219

You can specify the name of Context when you enable migration and using the other commands in same way, you can find more info about this here.

enable-migrations -ContextTypeName <DbContext-Name-with-Namespaces> -MigrationsDirectory:<Migrations-Directory-Name>
Add-Migration -configuration <DbContext-Migrations-Configuration-Class-with-Namespaces> <Migrations-Name>
Update-Database -configuration <DbContext-Migrations-Configuration-Class-with-Namespaces> -Verbose

Note: Don't forget to change Default Project to be the same as ApplicationDbContext in Package Manager Console.

Also i think you forgot to call base.OnModelCreating(modelBuilder) when you override the method in ApplicationDbContext.

Upvotes: 1

Related Questions