EF 配置多个数据库

2019/07/31 10:32
阅读数 0

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 回车,搞定!

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部