Azure Cosmos DB (二) SQL API 操作

时间:2024-01-27 12:41:41

一,引言

  还记得国庆期间,我们学习了一下关于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     }
UserContext.cs
 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     }
UserModel.cs
 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     }
Appsettings.json
 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     }
Program.cs
 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     }
Startup.cs

 3,运行项目,查看测试结果

我们可以看到UserModel 表已初始化数据完成

 我们转到Azure Portal 上查看 "CNBATEBLOGWEB" 数据库下多了叫 “UserContext” 的 Container 这里的可以理解成存放表的容器

同时,我们可以看到 ”UserContext“ 下的 Item 多了两条 Usermodel 数据,我们分别进行查看,可以看到这两条数据就是刚刚生成的种子数据

ok,今天的分享就到此,撒花是