EF 配置多個數據庫


1.先創建兩個DbContext

using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Reflection;
using Abp.EntityFramework;

namespace TestProject.EntityFramework
{
    public class TestProjectDbContext : AbpDbContext
    {
        //TODO: Define an IDbSet for each Entity...

        //Example:
        //public virtual IDbSet<User> Users { get; set; }

        /* NOTE: 
         *   Setting "Default" to base class helps us when working migration commands on Package Manager Console.
         *   But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not
         *   pass connection string name to base classes. ABP works either way.
         */
        public TestProjectDbContext()
            : base("Default")
        {

        }

        /* NOTE:
         *   This constructor is used by ABP to pass connection string defined in TestProjectDataModule.PreInitialize.
         *   Notice that, actually you will not directly create an instance of TestProjectDbContext since ABP automatically handles it.
         */
        public TestProjectDbContext(string nameOrConnectionString)
            : base(nameOrConnectionString)
        {

        }

        //This constructor is used in tests
        public TestProjectDbContext(DbConnection existingConnection)
         : base(existingConnection, false)
        {

        }

        public TestProjectDbContext(DbConnection existingConnection, bool contextOwnsConnection)
         : base(existingConnection, contextOwnsConnection)
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var typesRegister = Assembly.GetExecutingAssembly().GetTypes()
               .Where(type => !(string.IsNullOrEmpty(type.Namespace))).Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
            //刪除級聯
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }
}

 下面是新建的上下文,新建的DbContext不能含有DbContext(string nameOrConnectionString)構造函數,否則會被默認的連接名注入。

using Abp.EntityFramework;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace TestProject.EntityFramework
{
  
    public class TestSecondDbContext : AbpDbContext
    {
        //TODO: Define an IDbSet for each Entity...
        public DbSet<AuditLog> AuditLog { get; set; }
        //Example:
        //public virtual IDbSet<User> Users { get; set; }

        /* NOTE: 
         *   Setting "Default" to base class helps us when working migration commands on Package Manager Console.
         *   But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not
         *   pass connection string name to base classes. ABP works either way.
         */
        public TestSecondDbContext()
            : base("Second")
        {

        }

       //This constructor is used in tests
        public TestSecondDbContext(DbConnection existingConnection)
         : base(existingConnection, false)
        {

        }

        public TestSecondDbContext(DbConnection existingConnection, bool contextOwnsConnection)
         : base(existingConnection, contextOwnsConnection)
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var typesRegister = Assembly.GetExecutingAssembly().GetTypes()
               .Where(type => !(string.IsNullOrEmpty(type.Namespace))).Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
            //刪除級聯
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }
}

 

 2.創建實體類並且配置映射

public class AuditLogMap : EntityTypeConfiguration<AuditLog>
    {
        public AuditLogMap()
        {
            ToTable("AuditLog");
            HasKey(t => t.Id);

            Property(t => t.BrowserInfo).IsOptional().HasColumnType("varchar").HasMaxLength(512);
            Property(t => t.ClientIpAddress).IsOptional().HasColumnType("nvarchar").HasMaxLength(64);
            Property(t => t.ClientName).IsOptional().HasColumnType("varchar").HasMaxLength(128);
            Property(t => t.CustomData).IsOptional().HasColumnType("varchar").HasMaxLength(2000);
            Property(t => t.Exception).IsOptional().HasColumnType("varchar").HasMaxLength(2000);
            Property(t => t.ExecutionDuration).IsOptional();
            Property(t => t.ExecutionTime).IsOptional();
            Property(t => t.MethodName).IsOptional().HasColumnType("varchar").HasMaxLength(256);
            Property(t => t.Parameters).IsOptional().HasColumnType("nvarchar").HasMaxLength(1024);
            Property(t => t.ServiceName).IsOptional().HasColumnType("varchar").HasMaxLength(256);
        }
    }

 

public abstract class TestProjectRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<TestProjectDbContext, TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
    {
        protected TestProjectRepositoryBase(IDbContextProvider<TestProjectDbContext> dbContextProvider)
            : base(dbContextProvider)
        {

        }

        //add common methods for all repositories
    }

    public abstract class TestProjectRepositoryBase<TEntity> : TestProjectRepositoryBase<TEntity, int>
        where TEntity : class, IEntity<int>
    {
        protected TestProjectRepositoryBase(IDbContextProvider<TestProjectDbContext> dbContextProvider)
            : base(dbContextProvider)
        {

        }

        //do not add any method here, add to the class above (since this inherits it)
    }
 public abstract class TestSecondRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<TestSecondDbContext, TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
    {
        protected TestSecondRepositoryBase(IDbContextProvider<TestSecondDbContext> dbContextProvider)
            : base(dbContextProvider)
        {

        }

        //add common methods for all repositories
    }

    public abstract class TestSecondRepositoryBase<TEntity> : TestSecondRepositoryBase<TEntity, int>
        where TEntity : class, IEntity<int>
    {
        protected TestSecondRepositoryBase(IDbContextProvider<TestSecondDbContext> dbContextProvider)
            : base(dbContextProvider)
        {

        }

        //do not add any method here, add to the class above (since this inherits it)
    }

 

 

3.執行命令

First step
==========

enable-migrations -ContextTypeName TestProjectDbContext -MigrationsDirectory Migrations

enable-migrations -ContextTypeName TestSecondDbContext -MigrationsDirectory MigrationsSecond

Second Step
===========

add-migration -ConfigurationTypeName TestProject.Migrations.Configuration "InitialCreate" "InitialCreate"

add-migration -ConfigurationTypeName TestProject.MigrationsSecond.Configuration  "InitialCreate"

Third Step
==========

update-database -ConfigurationTypeName TestProject.Migrations.Configuration -verbose

update-database -ConfigurationTypeName TestProject.MigrationsSecond.Configuration -verbose

 4 開啟MSDTC

MSDTC(分布式交易協調器),協調跨多個數據庫、消息隊列、文件系統等資源管理器的事務。該服務的進程名為Msdtc.exe,該進程調用系統Microsoft Personal Web Server和Microsoft SQL Server。該服務用於管理多個服務器 .
位置:控制面板--管理工具--服務--Distributed Transaction Coordinator
依存關系:Remote Procedure Call(RPC)和Security Accounts Manager
建議:一般家用計算機涉及不到,除非你啟用Message Queuing服務,可以停止。
解決辦法: 1. 在windows控制面版-->管理工具-->服務-->Distributed Transaction Coordinator-->屬性-->啟動
        2.在CMD下運行"net start msdtc"開啟服務后正常。

注:如果在第1步Distributed Transaction Coordinator 無法啟動,則是因為丟失了日志文件,重新創建日志文件,再啟動就行了。重新創建 MSDTC 日志,並重新啟動服務的步驟如下:
(1) 單擊"開始",單擊"運行",輸入 cmd 后按"確定"。
(2) 輸入:msdtc -resetlog (注意運行此命令時,不要執行掛起的事務)
(3) 最后輸入:net start msdtc 回車,搞定!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM