EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

EF实际使用过程中,常常会出现多个Context上下文单位情况,有时候多个DB数据库持久化,有时候也会用一个DB数据持久化。如果是用云DB持久化,多个DB数据库就会增加成本。

新建一个如下结构的解决方案 Model1中放identity及扩展表

                                                Model2放自定义的DBContext

                                                WebApp来测试持久化 引用Model1和Model2

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

一、Model1NuGet安装EF (MySQL)

1、 Pomelo.EntityFrameworkCore.MySql

2、Pomelo.EntityFrameworkCore.MySql.Design

3、Microsoft.EntityFrameworkCore.Tools

如果是SqlServer则安装1、Microsoft.EntityFrameworkCore

2、Microsoft.EntityFrameworkCore.SqlServer

由于EF的强大功能,正文的具体实现过程都一样(就是数据链接字符串有一点区别)。

 

 

 

 

 

 

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

Model2修改csproj安装EF,将Model1csproj的ItemGroup复制到Model2中

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

二、新建identity用户角色实体类和数据库上下文

用户类和角色类 

 public class ApplicationUser : IdentityUser
    {
        //扩展用户属性
    }
    public class ApplicationRole : IdentityRole
    {
        //扩展角色属性
    }

数据库上下文

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
        }
    }

Model2中添加实体类及数据库上下文

public class BloggingContext : DbContext
    {
        public BloggingContext(DbContextOptions<BloggingContext> options)
            : base(options)
        { }

        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public ICollection<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }

三、在appsettings.json文件中配置数据库连接字符串

"ConnectionStrings": {
    "DefaultConnection": "Server=127.0.0.1;database=MoreContestTest;uid=root;password=pwd123456;TreatTinyAsBoolean=true"
  },

注意TreatTinyAsBoolean=true 最好加上   原因:bool类型字段对应到ef会生产bit字段。如果不在连接字符串中添加TreatTinyAsBoolean=true 插入数据的时候会报Unable to cast object of type 'System.Boolean' to type 'System.Int16这个错
 

SqlServer链接字符串

"ConnectionStrings": {
    "DefaultConnection": "Server=WIN-01406120129\\SQLEXPRESS;Database=MoreContestTest;Trusted_Connection=True;MultipleActiveResultSets=true"
  },

 

四、在Startup文件中注册数据库上下文服务和对identity进行相关设置

 services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
            services.AddIdentity<ApplicationUser, ApplicationRole>()
              .AddEntityFrameworkStores<ApplicationDbContext>()
              .AddDefaultTokenProviders();
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<BloggingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

现在数据库上下文连接字符串 全部指向了一个数据库

五、迁移(在程序包管理控制台中)

首先是Model1  默认项目必须选中Model1 

1、输入Enable-Migrations 

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

2、输入Add-Migration Initial -Context ApplicationDbContext建立快照

由于有多个上下文必须添加-Context ApplicationDbContext指定上下文

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer3、输入 Update-Database -Context ApplicationDbContext 升级数据库

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

4、完成之后 查看数据库生成情况

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

5、继续首先是Model2  默认项目必须选中Model2

按顺序执行下面三条指令

 Enable-Migrations

 Add-Migration Initial -Context BloggingContext

Update-Database -Context BloggingContext

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

这时候Model2中定义的表就追加到数据库中了

那么这样定义 究竟能不能用呢?

六、我们现在测试一下  Model1数据库写入情况

1、在webApp项目中添加Model1Test控制器

        #region 依赖注入
        private readonly RoleManager<ApplicationRole> _roleManager;
        private readonly UserManager<ApplicationUser> _userManager;
        public Model1TestController(
            UserManager<ApplicationUser> userManager,
            RoleManager<ApplicationRole> roleManager)
        {
            _roleManager = roleManager;
            _userManager = userManager;
        }
        #endregion

        public async Task<IActionResult> IndexAsync()
        {
            ApplicationUser user = new ApplicationUser
            {
                UserName = "Admin"
            };
            var result = await _userManager.CreateAsync(user, "123456");
            if (result.Succeeded)
            {
                return Content("yes");
            }
            return Content("no");

        }

现在访问一下对应的地址 看能否正常写入数据

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

写入成功 到数据库中查看数据是否写入成功

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

2、继续测试写入Model2数据库写入情况

private BloggingContext _context;

        public Model2TestController(BloggingContext context)
        {
            _context = context;
        }

        public async Task<IActionResult> IndexAsync()
        {

            Blog blog = new Blog
            {
                Url = "Test"
            };
            await _context.AddAsync(blog);
            int x =await _context.SaveChangesAsync();
            if (x > 0)
            {
                return Content("ok");
            }
            return Content("no");
        }

现在访问一下对应的地址 看能否正常写入数据

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

写入正常

七、测试一下 Model1的自定义表 然后添加一个控制器 测试混合写入

1、在Model1中添加TableTest1实体类

public class TablesTest1
    {
        public int TablesTest1Id { get; set; }
        public string TablesTest1Name { get; set; }
    }

2、ApplicationDbContext中添加映射

 public DbSet<TablesTest1> TablesTest1 { get; set; }

3、在Model1中启动迁移

Add-Migration Initial1 -Context ApplicationDbContext

Update-Database -Context ApplicationDbContext 

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

表成功追加到数据库中

最后测试写入

5、新建MoreContest控制器

private ApplicationDbContext _applicationDbContext;
        private BloggingContext _bloggingContext;
        private readonly RoleManager<ApplicationRole> _roleManager;
        private readonly UserManager<ApplicationUser> _userManager;
        public MoreContestController(
            UserManager<ApplicationUser> userManager,
            RoleManager<ApplicationRole> roleManager,
            ApplicationDbContext applicationDbContext,
            BloggingContext bloggingContext)
        {
            _roleManager = roleManager;
            _userManager = userManager;
            _applicationDbContext = applicationDbContext;
            _bloggingContext = bloggingContext;
        }

        public async Task<IActionResult> AddAsync()
        {
            //使用Identity
            ApplicationUser user = new ApplicationUser
            {
                UserName = "Admin2"
            };
            var result = await _userManager.CreateAsync(user, "123456");
            //使用ApplicationDbContext
            Blog blog = new Blog
            {
                Url = "Test2"
            };
            _bloggingContext.Add(blog);
            int x = _bloggingContext.SaveChanges();
            //使用BloggingContext
            TablesTest1 tablesTest1 = new TablesTest1
            {
                TablesTest1Name = "tablesTest2"
            };
            _applicationDbContext.Add(tablesTest1);
            int y = _applicationDbContext.SaveChanges();
            if (result.Succeeded && x>0 && y>0)
            {
                return Content("ok");
            }
            return Content("no");
        }

现在访问一下对应的地址 看能否正常写入数据

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

EF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServerEF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServerEF Code First多个Context上下文,使用一个DB数据库,附带identity数据表扩展。使用MySQL或者SqlServer

全部写入成功