一,引言
还记得国庆期间,我们学习了一下关于Azure Cosmos DB 的一些基础知识以及Azure Cosmos DB 的几种支持数据库类型。今天就开始分享一些实战操作,如何通过Azure Portal 创建 Cosmos DB,以及在实际项目中如何通过代码操作数据库。
今天要演示的是 Core(SQL) 核心,SQL API 是具有丰富的SQL查询功能的无架构 JSON 数据库引擎,它是以 json 形式的文档数据库。同时微软提供了对应的 EF 的操作包 ----- Microsoft.EntityFrameworkCore.Cosmos,使得我们很轻松的使用原有EF操作数据库的模式进行操作 Cosmos DB。
注意这里使用的 Microsoft.EntityFrameworkCore.Cosmos 仅适用于 Azure Cosmos DB 的 SQL API
--------------------我是分割线--------------------
1,Azure Cosmos DB (一) 入门介绍
2,Azure Cosmos DB (二) SQL API 操作
二,正文
1, 创建Azure Cosmos DB
在Azure portal 中点击 “+ 创建资源”,在搜索框中输入 “Azure Cosmos DB” 进行搜索
点击 “Create” ,进行开始创建
Resource Group:"Web_Test_DB_RG"
Account Name:"cnbateblogwebcosmosdb"
API 选择:Core(SQL)
Capacity mode 选择默认 :“Provisioned throughtput”(预配的吞吐量)
其他都选择默认。点击 “Review + create” 进行创建前的预校验。
使用Azure Cosmos DB 免费层时,将在账户中免费获得 400 RU/秒和 5GB 的存储。每个订阅最多可对一个账户启用免费层。预计每个账户每月有24美元的折扣。
可以看到验证提示 “Validation Sucess”,点击 ”Create“ 进行创建
等待几分钟后,我们可以在 "Web_Test_DB_RG" 中找到刚刚创建好的叫 ”cnbateblogwebcosmosdb“ 的 Cosmos DB 了
点击进去,找到 Data Explorer ,点击 ”New Database“ 新建数据库
或者点击 ”New Container“ 旁边的小箭头,进行下拉选择创建新的数据库。
Database id:”CNBATEBLOGWEB“
点击 “OK” ,进行创建
可以看到 “CNBATEBLOGWEB” 的 Database 已创建好了。
2,项目添加对Cosmos DB 的依赖包
2.1,安装 “Microsoft.EntityFrameworkCore”,“Microsoft.EntityFrameworkCore.Cosmos”
使用程序包管理控制台进行安装
Install-Package Microsoft.EntityFrameworkCore -Version 3.1.8
Install-Package Microsoft.EntityFrameworkCore.Cosmos -Version 3.1.8
2.2,要创建所需的容器并插入种子数据
配置环境,此时需要cosmosDB 的 Endpoint,Key,DatabaseName
图中对应的 URL=》Endpoint,PRIMARK KEY=》Key,
上面步骤中创建的叫 “CNBATEBLOGWEB” 的我们需要的DatabaseName
整理好刚才需要的三个参数,添加到项目的配置文件中 也就是 appsettings.json 文件中
创建UserModel 实体,UserContext,重写 OnConfiguring 方法,调用UseCosmos 方法
重写 “OnModelCreating” 创建数据数据映射关系
”ConfigrueServices“ 中添加对 “UserContext” 的依赖注入
生产种子数据,先将已有的数据库进行删除操作,再进行添加操作以及生成种子数据
完整代码
1 public class UserContext : DbContext 2 { 3 public UserContext(DbContextOptions<UserContext> options) : base(options) 4 { 5 6 } 7 8 public DbSet<UserModel> Users { get; set; } 9 10 /// <summary> 11 /// 重写连接数据库 12 /// </summary> 13 /// <param name="optionsBuilder"></param> 14 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 15 { 16 // 从 appsetting.json 中获取配置信息 17 var config = new ConfigurationBuilder() 18 .SetBasePath(Directory.GetCurrentDirectory()) 19 .AddJsonFile("appsettings.json") 20 .Build(); 21 22 // 定义要使用的数据库 23 optionsBuilder.UseCosmos(Appsettings.app("CosmosDB", "Endpoint"), Appsettings.app("CosmosDB", "Key"), Appsettings.app("CosmosDB", "DataBase")); 24 } 25 26 protected override void OnModelCreating(ModelBuilder modelBuilder) 27 { 28 //针对于HasData限制(即使主键是由数据库生成的自动增长),也需要指定主键 29 30 //调用EnsureCreated方法只针对与添加数据有效,但是数据库如果有数据的话, 31 //也就是对数据更改将无效 32 Console.WriteLine("**********UserModel表开始初始化数据**********"); 33 #region 数据库数据映射 34 modelBuilder.Entity<UserModel>().HasData( 35 //new Blog{Id=1,Name="DDD领域驱动模型"}, 36 new UserModel { Id = 1, Name = "EntityFramework Core 3.1.1" }, 37 new UserModel { Id = 2, Name = "EntityFramework Core 3.1.6" }); 38 39 #endregion 40 41 42 } 43 44 }
1 public class UserModel 2 { 3 public int Id { get; set; } 4 5 public string Name { get; set; } 6 7 public int Age { get; set; } 8 9 public string Address { get; set; } 10 11 public string Remark { get; set; } 12 }
1 /// <summary> 2 /// appsettings.json操作类 3 /// </summary> 4 public class Appsettings 5 { 6 static IConfiguration Configuration { get; set; } 7 static string contentPath { get; set; } 8 9 public Appsettings(string contentPath) 10 { 11 string Path = "appsettings.json"; 12 13 14 //如果你把配置文件 是 根据环境变量来分开了,可以这样写 15 //string Path = $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json"; 16 17 //var contentPath = env.ContentRootPath; 18 Configuration = new ConfigurationBuilder() 19 .SetBasePath(contentPath) 20 .Add(new JsonConfigurationSource { Path = Path, Optional = false, ReloadOnChange = true })//这样的话,可以直接读目录里的json文件,而不是 bin 文件夹下的,所以不用修改复制属性 21 .Build(); 22 } 23 24 /// <summary> 25 /// 封装要操作的字符 26 /// </summary> 27 /// <param name="sections"></param> 28 /// <returns></returns> 29 public static string app(params string[] sections) 30 { 31 try 32 { 33 var val = string.Empty; 34 for (int i = 0; i < sections.Length; i++) 35 { 36 val += sections[i] + ":"; 37 } 38 39 return Configuration[val.TrimEnd(':')]; 40 } 41 catch (Exception) 42 { 43 return ""; 44 } 45 } 46 }
1 public class Program 2 { 3 public static void Main(string[] args) 4 { 5 var host = CreateHostBuilder(args).Build(); 6 // 创建可用于解析作用域服务的新 Microsoft.Extensions.DependencyInjection.IServiceScope。 7 using (var scope = host.Services.CreateScope()) 8 { 9 var services = scope.ServiceProvider; 10 var loggerFactory = services.GetRequiredService<ILoggerFactory>(); 11 var env = services.GetRequiredService<IWebHostEnvironment>(); 12 if (env.IsDevelopment()) 13 { 14 try 15 { 16 // 从 system.IServicec提供程序获取 T 类型的服务。 17 var context = services.GetRequiredService<UserContext>(); 18 19 context.Database.EnsureDeleted(); 20 Console.WriteLine("**********开始初始化数据**********"); 21 context.Database.EnsureCreated(); 22 23 } 24 catch (Exception e) 25 { 26 var logger = loggerFactory.CreateLogger<Program>(); 27 logger.LogError(e, "Error occured seeding the Database."); 28 } 29 } 30 } 31 32 // 运行 web 应用程序并阻止调用线程, 直到主机关闭。 33 // 创建完 WebHost 之后,便调用它的 Run 方法,而 Run 方法会去调用 WebHost 的 StartAsync 方法 34 // 将Initialize方法创建的Application管道传入以供处理消息 35 // 执行HostedServiceExecutor.StartAsync方法 36 37 host.Run(); 38 } 39 40 public static IHostBuilder CreateHostBuilder(string[] args) => 41 Host.CreateDefaultBuilder(args) 42 .ConfigureWebHostDefaults(webBuilder => 43 { 44 webBuilder 45 .UseUrls("http://*:9001") 46 .UseStartup<Startup>(); 47 }); 48 }
1 public class Startup 2 { 3 public Startup(IConfiguration configuration, IWebHostEnvironment env) 4 { 5 Env = env; 6 Configuration = configuration; 7 } 8 9 public IConfiguration Configuration { get; } 10 11 public IWebHostEnvironment Env { get; } 12 13 // This method gets called by the runtime. Use this method to add services to the container. 14 public void ConfigureServices(IServiceCollection services) 15 { 16 services.AddSingleton(new Appsettings(Env.ContentRootPath)); 17 18 services.AddDbContext<UserContext>(options => options.UseCosmos(Appsettings.app("CosmosDB", "Endpoint"), Appsettings.app("CosmosDB", "Key"), Appsettings.app("CosmosDB", "DataBase"))); 19 20 services.AddControllersWithViews(); 21 } 22 23 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 24 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 25 { 26 if (env.IsDevelopment()) 27 { 28 app.UseDeveloperExceptionPage(); 29 } 30 else 31 { 32 app.UseExceptionHandler("/Home/Error"); 33 } 34 app.UseStaticFiles(); 35 36 app.UseRouting(); 37 38 app.UseAuthorization(); 39 40 app.UseEndpoints(endpoints => 41 { 42 endpoints.MapControllerRoute( 43 name: "default", 44 pattern: "{controller=Home}/{action=Index}/{id?}"); 45 }); 46 } 47 }
3,运行项目,查看测试结果
我们可以看到UserModel 表已初始化数据完成
我们转到Azure Portal 上查看 "CNBATEBLOGWEB" 数据库下多了叫 “UserContext” 的 Container 这里的可以理解成存放表的容器
同时,我们可以看到 ”UserContext“ 下的 Item 多了两条 Usermodel 数据,我们分别进行查看,可以看到这两条数据就是刚刚生成的种子数据
ok,今天的分享就到此,撒花是