如何重用现有的 DbContext 作为新项目的基础 class?

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

我有一个现有的 DbContext class,我想将其用作其他 Web 项目的基础 class。该 DbContext 包含一个非常完整的 table 结构,用于注册公司和具有相关信息的人员。

当开始一个新项目时,我不想一次又一次地创建相同的结构!因此,我尝试将现有的 DbContext 重新用作我的新项目的基础 class,并仅添加新的 table 以使其在新应用程序中按需要工作。

但是,我找不到让它工作的方法! DbContext 基础 class 如下所示,它来自另一个项目:

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)
        {
            ...
        }
}

这是我的新项目的 ApplicationDbContext:

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

如您所见,这根本不起作用,我不知道如何才能达到我想要的结果。我什至不知道是否可以不复制 TemplateDbContext class 中的所有代码。 我目前完成的最好的事情是仅生成 TemplateDbContext,方法是在新项目中使用 Package Manager Console 执行 Add-Migration。所以迁移错过了定义到 ApplicationDbContext class.

中的所有 DbSet

我需要什么样的结构才能做到这一点?

你可以在enable migration的时候指定Context的名字,其他的命令也一样,你可以找到更多的信息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

注意:不要忘记将默认项目更改为与[=23=中的ApplicationDbContext相同]包管理器控制台.

我还认为你在重写 ApplicationDbContext 中的方法时忘记调用 base.OnModelCreating(modelBuilder)