使用 Azure Cosmos DB 模拟器在本地进行开发

选择一个 API

模拟器的一个常见用例是在构建应用程序时充当开发数据库。 使用模拟器进行开发可帮助你了解为 Azure Cosmos DB 等数据库创建和建模数据的特点,且不会产生任何服务费用。 此外,将模拟器用作自动化工作流的一部分,可以确保能够运行相同的集成测试套件。 模拟器可以确保在本地开发计算机和远程持续集成作业中运行相同的测试。

先决条件

安装模拟器

模拟器有多个变体,每个变体的安装过程都相对顺畅。

若要开始,请在本地计算机上下载并安装最新版本的 Azure Cosmos DB 模拟器。

提示

模拟器发行说明一文列出了所有可用版本以及每个版本中所做的功能更新。

  1. 下载 Azure Cosmos DB 模拟器

  2. 使用“管理权限”在本地计算机上运行安装程序。

  3. 模拟器会自动安装相应的开发人员证书,并在本地计算机上配置防火墙规则。

若要开始,请在本地计算机上下载并安装最新版本的 Azure Cosmos DB 模拟器。

提示

模拟器发行说明一文列出了所有可用版本以及每个版本中所做的功能更新。

  1. 下载 Azure Cosmos DB 模拟器

  2. 使用“管理权限”在本地计算机上运行安装程序。

  3. 模拟器会自动安装相应的开发人员证书,并在本地计算机上配置防火墙规则。

若要开始,请在本地计算机上下载并安装最新版本的 Azure Cosmos DB 模拟器。

提示

模拟器发行说明一文列出了所有可用版本以及每个版本中所做的功能更新。

  1. 下载 Azure Cosmos DB 模拟器

  2. 使用“管理权限”在本地计算机上运行安装程序。

  3. 模拟器会自动安装相应的开发人员证书,并在本地计算机上配置防火墙规则。

启动模拟器

下载后,启用指定的 API 并启动模拟器。

  1. %ProgramFiles%\Azure Cosmos DB Emulator 路径上启动模拟器的可执行文件 (Microsoft.Azure.Cosmos.Emulator.exe)。 使用以下参数来配置模拟器:

    说明
    EnableCassandraEndpoint 启用 API for Apache Cassandra 终结点。
    CassandraPort 用于终结点的端口号。
    Microsoft.Azure.Cosmos.Emulator.exe /EnableCassandraEndpoint /CassandraPort=65200
    

    注意

    有关命令行参数的详细信息,请参阅 命令行参数

  2. 模拟器使用 URL https://localhost:8081/_explorer/index.html 自动打开数据资源管理器。

  1. %ProgramFiles%\Azure Cosmos DB Emulator 路径上启动模拟器的可执行文件 (Microsoft.Azure.Cosmos.Emulator.exe)。 使用以下参数来配置模拟器:

    说明
    EnableGremlinEndpoint 启用 API for Apache Gremlin。
    GremlinPort 用于终结点的端口号。
    Microsoft.Azure.Cosmos.Emulator.exe /EnableGremlinEndpoint /GremlinPort=65400
    

    注意

    有关命令行参数的详细信息,请参阅 命令行参数

  2. 模拟器使用 URL https://localhost:8081/_explorer/index.html 自动打开数据资源管理器。

  1. %ProgramFiles%\Azure Cosmos DB Emulator 路径上启动模拟器的可执行文件 (Microsoft.Azure.Cosmos.Emulator.exe)。 使用以下参数来配置模拟器:

    说明
    EnableTableEndpoint 启用 API for Table 终结点。
    TablePort 用于终结点的端口号。
    Microsoft.Azure.Cosmos.Emulator.exe /EnableTableEndpoint /TablePort=65500
    

    注意

    有关命令行参数的详细信息,请参阅 命令行参数

  2. 模拟器使用 URL https://localhost:8081/_explorer/index.html 自动打开数据资源管理器。

  1. 在 Windows“开始菜单”中选择应用程序,启动模拟器。

  2. 或者,可以在 %ProgramFiles%\Azure Cosmos DB Emulator 路径启动模拟器的可执行文件 (Microsoft.Azure.Cosmos.Emulator.exe)。

  3. 此外,还可以从命令行启动模拟器。 使用以下参数来配置模拟器:

    说明
    Port 用于 API for NoSQL 终结点的端口号。
    Microsoft.Azure.Cosmos.Emulator.exe /Port=65000
    

    注意

    有关命令行参数的详细信息,请参阅 命令行参数

  4. 模拟器使用 URL https://localhost:8081/_explorer/index.html 自动打开数据资源管理器。

  1. %ProgramFiles%\Azure Cosmos DB Emulator 路径上启动模拟器的可执行文件 (Microsoft.Azure.Cosmos.Emulator.exe)。 使用以下参数来配置模拟器:

    说明
    EnableMongoDbEndpoint 在指定的 MongoDB 版本中启用 API for MongoDB 终结点。
    MongoPort 用于终结点的端口号。
    Microsoft.Azure.Cosmos.Emulator.exe /EnableMongoDbEndpoint=4.0 /MongoPort=65200
    

    注意

    有关模拟器支持的命令行参数和 MongoDB 版本的详细信息,请参阅命令行参数

  2. 模拟器使用 URL https://localhost:8081/_explorer/index.html 自动打开数据资源管理器。

导入模拟器的 TLS/SSL 证书

导入模拟器的 TLS/SSL 证书,以便在客户端不禁用 TLS/SSL的情况下将模拟器与首选开发人员 SDK 一起使用。

仿真器的 Windows 本地安装会自动导入 TLS/SSL 证书。 无需进一步操作。

仿真器的 Windows 本地安装会自动导入 TLS/SSL 证书。 无需进一步操作。

仿真器的 Windows 本地安装会自动导入 TLS/SSL 证书。 无需进一步操作。

从 SDK 连接到仿真器

每个 SDK 都包含一个客户端类,通常用于将 SDK 连接到 Azure Cosmos DB 帐户。 使用模拟器的凭据,可以改为将 SDK 连接到模拟器实例。

使用 Azure Cosmos DB API for NoSQL .NET SDK 从 .NET 应用程序连接到模拟器。

  1. 从空文件夹开始。

  2. 创建新的 .NET 控制台应用程序

    dotnet new console
    
  3. 从 NuGet 添加 Microsoft.Azure.Cosmos 包。

    dotnet add package Microsoft.Azure.Cosmos
    
  4. 打开 Program.cs 文件。

  5. 删除文件中的任何现有内容。

  6. Microsoft.Azure.Cosmos 命名空间添加一个 using 块。

// <imports>
using Microsoft.Azure.Cosmos;
// </imports>

// <client>
using CosmosClient client = new(
    accountEndpoint: "https://localhost:8081/",
    authKeyOrResourceToken: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);
// </client>

// <resources>
Database database = await client.CreateDatabaseIfNotExistsAsync(
    id: "cosmicworks",
    throughput: 400
);

Container container = await database.CreateContainerIfNotExistsAsync(
    id: "products",
    partitionKeyPath: "/id"
);
// </resources>

// <upsert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

await container.UpsertItemAsync(item);
// </upsert>
  1. 使用仿真器的凭据创建 CosmosClient 的新实例。
// <imports>
using Microsoft.Azure.Cosmos;
// </imports>

// <client>
using CosmosClient client = new(
    accountEndpoint: "https://localhost:8081/",
    authKeyOrResourceToken: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);
// </client>

// <resources>
Database database = await client.CreateDatabaseIfNotExistsAsync(
    id: "cosmicworks",
    throughput: 400
);

Container container = await database.CreateContainerIfNotExistsAsync(
    id: "products",
    partitionKeyPath: "/id"
);
// </resources>

// <upsert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

await container.UpsertItemAsync(item);
// </upsert>
  1. 使用 CreateDatabaseIfNotExistsAsyncCreateContainerIfNotExistsAsync 创建新的数据库和容器。
// <imports>
using Microsoft.Azure.Cosmos;
// </imports>

// <client>
using CosmosClient client = new(
    accountEndpoint: "https://localhost:8081/",
    authKeyOrResourceToken: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);
// </client>

// <resources>
Database database = await client.CreateDatabaseIfNotExistsAsync(
    id: "cosmicworks",
    throughput: 400
);

Container container = await database.CreateContainerIfNotExistsAsync(
    id: "products",
    partitionKeyPath: "/id"
);
// </resources>

// <upsert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

await container.UpsertItemAsync(item);
// </upsert>
  1. 使用 UpsertItemAsync 在容器中创建新项。
// <imports>
using Microsoft.Azure.Cosmos;
// </imports>

// <client>
using CosmosClient client = new(
    accountEndpoint: "https://localhost:8081/",
    authKeyOrResourceToken: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);
// </client>

// <resources>
Database database = await client.CreateDatabaseIfNotExistsAsync(
    id: "cosmicworks",
    throughput: 400
);

Container container = await database.CreateContainerIfNotExistsAsync(
    id: "products",
    partitionKeyPath: "/id"
);
// </resources>

// <upsert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

await container.UpsertItemAsync(item);
// </upsert>
  1. 运行 .NET 应用程序。

    dotnet run
    

    警告

    如果收到 SSL 错误,可能需要为应用程序禁用 TLS/SSL。 如果在本地计算机上进行开发,在容器中使用 Azure Cosmos DB 模拟器,并且尚未导入容器的 SSL 证书,则通常会发生这种情况。 要解决此问题,请在创建客户端之前配置客户端选项,禁用 TLS/SSL 验证:

    CosmosClientOptions options = new ()
    {
        HttpClientFactory = () => new HttpClient(new HttpClientHandler()
        {
            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
        }),
        ConnectionMode = ConnectionMode.Gateway,
    };
    
    using CosmosClient client = new(
      ...,
      ...,
      clientOptions: options
    );
    

提示

有关可使用 .NET SDK 执行的更多操作,请参阅 .NET 开发人员指南

使用 MongoDB .NET 驱动程序 从 .NET 应用程序连接到模拟器。

  1. 从空文件夹开始。

  2. 创建新的 .NET 控制台应用程序

    dotnet new console
    
  3. 从 NuGet 添加 MongoDB.Driver 包。

    dotnet add package MongoDB.Driver
    
  4. 打开 Program.cs 文件。

  5. 删除文件中的任何现有内容。

  6. MongoDB.Driver 命名空间添加一个 using 块。

// <imports>
using MongoDB.Driver;
// </imports>

// <client>
var client = new MongoClient(
    "mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/admin?ssl=true&retrywrites=false"
);
// </client>

// <resources>
var database = client.GetDatabase("cosmicworks");

var collection = database.GetCollection<dynamic>("products");
// </resources>

// <insert>
var item = new
{
    name = "Kiama classic surfboard"
};

await collection.InsertOneAsync(item);
// </insert>
  1. 使用模拟器的凭据创建 MongoClient 的新实例。
// <imports>
using MongoDB.Driver;
// </imports>

// <client>
var client = new MongoClient(
    "mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/admin?ssl=true&retrywrites=false"
);
// </client>

// <resources>
var database = client.GetDatabase("cosmicworks");

var collection = database.GetCollection<dynamic>("products");
// </resources>

// <insert>
var item = new
{
    name = "Kiama classic surfboard"
};

await collection.InsertOneAsync(item);
// </insert>
  1. 使用 GetDatabaseGetCollection<> 获取数据库和容器。
// <imports>
using MongoDB.Driver;
// </imports>

// <client>
var client = new MongoClient(
    "mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/admin?ssl=true&retrywrites=false"
);
// </client>

// <resources>
var database = client.GetDatabase("cosmicworks");

var collection = database.GetCollection<dynamic>("products");
// </resources>

// <insert>
var item = new
{
    name = "Kiama classic surfboard"
};

await collection.InsertOneAsync(item);
// </insert>
  1. 使用 InsertOneAsync 在 XXX 中创建新项。
// <imports>
using MongoDB.Driver;
// </imports>

// <client>
var client = new MongoClient(
    "mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/admin?ssl=true&retrywrites=false"
);
// </client>

// <resources>
var database = client.GetDatabase("cosmicworks");

var collection = database.GetCollection<dynamic>("products");
// </resources>

// <insert>
var item = new
{
    name = "Kiama classic surfboard"
};

await collection.InsertOneAsync(item);
// </insert>
  1. 运行 .NET 应用程序。

    dotnet run
    

使用 Apache Cassandra .NET 驱动程序 从 .NET 应用程序连接到模拟器。

  1. 从空文件夹开始。

  2. 创建新的 .NET 控制台应用程序

    dotnet new console
    
  3. 从 NuGet 添加 CassandraCSharpDriver 包。

    dotnet add package CassandraCSharpDriver
    
  4. 打开 Program.cs 文件。

  5. 删除文件中的任何现有内容。

  6. Cassandra 命名空间添加一个 using 块。

// <imports>
using Cassandra;
// </imports>

// <client>
var options = new SSLOptions(
    sslProtocol: System.Security.Authentication.SslProtocols.Tls12,
    checkCertificateRevocation: true,
    remoteCertValidationCallback: (_, _, _, policyErrors) => policyErrors == System.Net.Security.SslPolicyErrors.None);

using var cluster = Cluster.Builder()
    .WithCredentials(
        username: "localhost",
        password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    )
    .WithPort(
        port: 10350
    )
    .AddContactPoint(
        address: "localhost"
    )
    .WithSSL(
        sslOptions: options
    )
    .Build();

using var session = cluster.Connect();
// </client>

// <resources>
var createKeyspace = await session.PrepareAsync("CREATE KEYSPACE IF NOT EXISTS cosmicworks WITH replication = {'class':'basicclass', 'replication_factor': 1};");
await session.ExecuteAsync(createKeyspace.Bind());

var createTable = await session.PrepareAsync("CREATE TABLE IF NOT EXISTS cosmicworks.products (id text PRIMARY KEY, name text)");
await session.ExecuteAsync(createTable.Bind());
// </resources>

// <insert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

var createItem = await session.PrepareAsync("INSERT INTO cosmicworks.products (id, name) VALUES (?, ?)");

var createItemStatement = createItem.Bind(item.id, item.name);

await session.ExecuteAsync(createItemStatement);
// </insert>
  1. 使用模拟器的凭据创建 Cluster 的新实例。 使用 Connect 新建会话。
// <imports>
using Cassandra;
// </imports>

// <client>
var options = new SSLOptions(
    sslProtocol: System.Security.Authentication.SslProtocols.Tls12,
    checkCertificateRevocation: true,
    remoteCertValidationCallback: (_, _, _, policyErrors) => policyErrors == System.Net.Security.SslPolicyErrors.None);

using var cluster = Cluster.Builder()
    .WithCredentials(
        username: "localhost",
        password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    )
    .WithPort(
        port: 10350
    )
    .AddContactPoint(
        address: "localhost"
    )
    .WithSSL(
        sslOptions: options
    )
    .Build();

using var session = cluster.Connect();
// </client>

// <resources>
var createKeyspace = await session.PrepareAsync("CREATE KEYSPACE IF NOT EXISTS cosmicworks WITH replication = {'class':'basicclass', 'replication_factor': 1};");
await session.ExecuteAsync(createKeyspace.Bind());

var createTable = await session.PrepareAsync("CREATE TABLE IF NOT EXISTS cosmicworks.products (id text PRIMARY KEY, name text)");
await session.ExecuteAsync(createTable.Bind());
// </resources>

// <insert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

var createItem = await session.PrepareAsync("INSERT INTO cosmicworks.products (id, name) VALUES (?, ?)");

var createItemStatement = createItem.Bind(item.id, item.name);

await session.ExecuteAsync(createItemStatement);
// </insert>
  1. 使用 PrepareAsyncExecuteAsync 创建新的数据库和容器。
// <imports>
using Cassandra;
// </imports>

// <client>
var options = new SSLOptions(
    sslProtocol: System.Security.Authentication.SslProtocols.Tls12,
    checkCertificateRevocation: true,
    remoteCertValidationCallback: (_, _, _, policyErrors) => policyErrors == System.Net.Security.SslPolicyErrors.None);

using var cluster = Cluster.Builder()
    .WithCredentials(
        username: "localhost",
        password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    )
    .WithPort(
        port: 10350
    )
    .AddContactPoint(
        address: "localhost"
    )
    .WithSSL(
        sslOptions: options
    )
    .Build();

using var session = cluster.Connect();
// </client>

// <resources>
var createKeyspace = await session.PrepareAsync("CREATE KEYSPACE IF NOT EXISTS cosmicworks WITH replication = {'class':'basicclass', 'replication_factor': 1};");
await session.ExecuteAsync(createKeyspace.Bind());

var createTable = await session.PrepareAsync("CREATE TABLE IF NOT EXISTS cosmicworks.products (id text PRIMARY KEY, name text)");
await session.ExecuteAsync(createTable.Bind());
// </resources>

// <insert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

var createItem = await session.PrepareAsync("INSERT INTO cosmicworks.products (id, name) VALUES (?, ?)");

var createItemStatement = createItem.Bind(item.id, item.name);

await session.ExecuteAsync(createItemStatement);
// </insert>
  1. 使用 ExecuteAsync 在表中创建新项。 使用 Bind 为项分配属性。
// <imports>
using Cassandra;
// </imports>

// <client>
var options = new SSLOptions(
    sslProtocol: System.Security.Authentication.SslProtocols.Tls12,
    checkCertificateRevocation: true,
    remoteCertValidationCallback: (_, _, _, policyErrors) => policyErrors == System.Net.Security.SslPolicyErrors.None);

using var cluster = Cluster.Builder()
    .WithCredentials(
        username: "localhost",
        password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    )
    .WithPort(
        port: 10350
    )
    .AddContactPoint(
        address: "localhost"
    )
    .WithSSL(
        sslOptions: options
    )
    .Build();

using var session = cluster.Connect();
// </client>

// <resources>
var createKeyspace = await session.PrepareAsync("CREATE KEYSPACE IF NOT EXISTS cosmicworks WITH replication = {'class':'basicclass', 'replication_factor': 1};");
await session.ExecuteAsync(createKeyspace.Bind());

var createTable = await session.PrepareAsync("CREATE TABLE IF NOT EXISTS cosmicworks.products (id text PRIMARY KEY, name text)");
await session.ExecuteAsync(createTable.Bind());
// </resources>

// <insert>
var item = new
{
    id = "68719518371",
    name = "Kiama classic surfboard"
};

var createItem = await session.PrepareAsync("INSERT INTO cosmicworks.products (id, name) VALUES (?, ?)");

var createItemStatement = createItem.Bind(item.id, item.name);

await session.ExecuteAsync(createItemStatement);
// </insert>
  1. 运行 .NET 应用程序。

    dotnet run
    

重要

在启动之前,API for Apache Gremlin 要求你在模拟器中创建资源。 创建名为 db1 的数据库和名为 coll1 的容器。 吞吐量设置与本指南无关,可以随意设置。

使用 Apache Gremlin .NET 驱动程序 从 .NET 应用程序连接到模拟器。

  1. 从空文件夹开始。

  2. 创建新的 .NET 控制台应用程序

    dotnet new console
    
  3. 从 NuGet 添加 Gremlin.Net 包。

    dotnet add package Gremlin.Net 
    
  4. 打开 Program.cs 文件。

  5. 删除文件中的任何现有内容。

  6. Gremlin.Net.Driver 命名空间添加一个 using 块。

// <imports>
using Gremlin.Net.Driver;
// </imports>

// <client>
var server = new GremlinServer(
    hostname: "localhost",
    port: 8901,
    username: "/dbs/db1/colls/coll1",
    password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);

using var client = new GremlinClient(
    gremlinServer: server,
    messageSerializer: new Gremlin.Net.Structure.IO.GraphSON.GraphSON2MessageSerializer()
);
// </client>

// <graph>
await client.SubmitAsync(
    requestScript: "g.V().drop()"
);
// </graph>

// <insert>
await client.SubmitAsync(
    requestScript: "g.addV('product').property('id', prop_id).property('name', prop_name)",
    bindings: new Dictionary<string, object>
    {
        { "prop_id", "68719518371" },
        { "prop_name", "Kiama classic surfboard" }
    }
);
// </insert>
  1. 使用模拟器的凭据创建 GremlinServerGremlinClient 的新实例。
// <imports>
using Gremlin.Net.Driver;
// </imports>

// <client>
var server = new GremlinServer(
    hostname: "localhost",
    port: 8901,
    username: "/dbs/db1/colls/coll1",
    password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);

using var client = new GremlinClient(
    gremlinServer: server,
    messageSerializer: new Gremlin.Net.Structure.IO.GraphSON.GraphSON2MessageSerializer()
);
// </client>

// <graph>
await client.SubmitAsync(
    requestScript: "g.V().drop()"
);
// </graph>

// <insert>
await client.SubmitAsync(
    requestScript: "g.addV('product').property('id', prop_id).property('name', prop_name)",
    bindings: new Dictionary<string, object>
    {
        { "prop_id", "68719518371" },
        { "prop_name", "Kiama classic surfboard" }
    }
);
// </insert>
  1. 使用 SubmitAsync 清理图形。
// <imports>
using Gremlin.Net.Driver;
// </imports>

// <client>
var server = new GremlinServer(
    hostname: "localhost",
    port: 8901,
    username: "/dbs/db1/colls/coll1",
    password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);

using var client = new GremlinClient(
    gremlinServer: server,
    messageSerializer: new Gremlin.Net.Structure.IO.GraphSON.GraphSON2MessageSerializer()
);
// </client>

// <graph>
await client.SubmitAsync(
    requestScript: "g.V().drop()"
);
// </graph>

// <insert>
await client.SubmitAsync(
    requestScript: "g.addV('product').property('id', prop_id).property('name', prop_name)",
    bindings: new Dictionary<string, object>
    {
        { "prop_id", "68719518371" },
        { "prop_name", "Kiama classic surfboard" }
    }
);
// </insert>
  1. 再次使用 SubmitAsync,可使用指定参数向图形添加新项。
// <imports>
using Gremlin.Net.Driver;
// </imports>

// <client>
var server = new GremlinServer(
    hostname: "localhost",
    port: 8901,
    username: "/dbs/db1/colls/coll1",
    password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
);

using var client = new GremlinClient(
    gremlinServer: server,
    messageSerializer: new Gremlin.Net.Structure.IO.GraphSON.GraphSON2MessageSerializer()
);
// </client>

// <graph>
await client.SubmitAsync(
    requestScript: "g.V().drop()"
);
// </graph>

// <insert>
await client.SubmitAsync(
    requestScript: "g.addV('product').property('id', prop_id).property('name', prop_name)",
    bindings: new Dictionary<string, object>
    {
        { "prop_id", "68719518371" },
        { "prop_name", "Kiama classic surfboard" }
    }
);
// </insert>
  1. 运行 .NET 应用程序。

    dotnet run
    

使用 适用于 .NET 的 Azure Tables SDK 从 .NET 应用程序连接到模拟器。

  1. 从空文件夹开始。

  2. 创建新的 .NET 控制台应用程序

    dotnet new console
    
  3. 从 NuGet 添加 Azure.Data.Tables 包。

    dotnet add package Azure.Data.Tables
    
  4. 打开 Program.cs 文件。

  5. 删除文件中的任何现有内容。

  6. Azure.Data.Tables 命名空间添加一个 using 块。

// <imports>
using Azure.Data.Tables;
// </imports>

// <client>
var serviceClient = new TableServiceClient(
    connectionString: "DefaultEndpointsProtocol=http;AccountName=localhost;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;TableEndpoint=http://localhost:8902/;"
);
// </client>

// <resources>
var client = serviceClient.GetTableClient(
    tableName: "cosmicworksproducts"
);

await client.CreateIfNotExistsAsync();
// </resources>

// <upsert>
var item = new Product
{
    RowKey = "68719518371",
    PartitionKey = "Surfboards",
    Name = "Kiama classic surfboard",
    Timestamp = DateTimeOffset.Now
};

await client.UpsertEntityAsync(
    entity: item,
    mode: TableUpdateMode.Replace
);
// </upsert>
  1. 使用模拟器的凭据创建 TableServiceClient 的新实例。
// <imports>
using Azure.Data.Tables;
// </imports>

// <client>
var serviceClient = new TableServiceClient(
    connectionString: "DefaultEndpointsProtocol=http;AccountName=localhost;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;TableEndpoint=http://localhost:8902/;"
);
// </client>

// <resources>
var client = serviceClient.GetTableClient(
    tableName: "cosmicworksproducts"
);

await client.CreateIfNotExistsAsync();
// </resources>

// <upsert>
var item = new Product
{
    RowKey = "68719518371",
    PartitionKey = "Surfboards",
    Name = "Kiama classic surfboard",
    Timestamp = DateTimeOffset.Now
};

await client.UpsertEntityAsync(
    entity: item,
    mode: TableUpdateMode.Replace
);
// </upsert>
  1. 使用 GetTableClient 创建带有表名称的 TableClient 的新实例。 然后使用 CreateIfNotExistsAsync 确保表存在。
// <imports>
using Azure.Data.Tables;
// </imports>

// <client>
var serviceClient = new TableServiceClient(
    connectionString: "DefaultEndpointsProtocol=http;AccountName=localhost;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;TableEndpoint=http://localhost:8902/;"
);
// </client>

// <resources>
var client = serviceClient.GetTableClient(
    tableName: "cosmicworksproducts"
);

await client.CreateIfNotExistsAsync();
// </resources>

// <upsert>
var item = new Product
{
    RowKey = "68719518371",
    PartitionKey = "Surfboards",
    Name = "Kiama classic surfboard",
    Timestamp = DateTimeOffset.Now
};

await client.UpsertEntityAsync(
    entity: item,
    mode: TableUpdateMode.Replace
);
// </upsert>
  1. 为项创建新 record 类型。
// <entity>
public record Product : Azure.Data.Tables.ITableEntity
{
    public required string RowKey { get; set; }

    public required string PartitionKey { get; set; }

    public required string Name { get; init; }

    public Azure.ETag ETag { get; set; }

    public DateTimeOffset? Timestamp { get; set; }
}
// </entity>
  1. 使用 UpsertEntityAsyncReplace 模式在表中创建新项。
// <imports>
using Azure.Data.Tables;
// </imports>

// <client>
var serviceClient = new TableServiceClient(
    connectionString: "DefaultEndpointsProtocol=http;AccountName=localhost;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;TableEndpoint=http://localhost:8902/;"
);
// </client>

// <resources>
var client = serviceClient.GetTableClient(
    tableName: "cosmicworksproducts"
);

await client.CreateIfNotExistsAsync();
// </resources>

// <upsert>
var item = new Product
{
    RowKey = "68719518371",
    PartitionKey = "Surfboards",
    Name = "Kiama classic surfboard",
    Timestamp = DateTimeOffset.Now
};

await client.UpsertEntityAsync(
    entity: item,
    mode: TableUpdateMode.Replace
);
// </upsert>
  1. 运行 .NET 应用程序。

    dotnet run
    

在 GitHub Actions CI 工作流中使用模拟器

若要运行可自动验证应用程序的持续集成工作负载,请将 Azure Cosmos DB 模拟器与所选框架的测试套件配合使用。 GitHub Action 的托管运行器的 windows-latest 变体中预装了Azure Cosmos DB 模拟器。

使用 .NET 内置测试驱动程序和测试框架(如 MSTest、 NUnit 或 XUnit)来运行测试套件。

  1. 验证应用程序的单元测试套件是否按预期运行。

    dotnet test
    
  2. 在 GitHub 存储库中创建新工作流,文件名为 .github/workflows/ci.yml

  3. 将作业添加到工作流,以便使用 PowerShell 启动 Azure Cosmos DB 模拟器并运行单元测试套件。

    name: Continuous Integration
    on:
      push:
        branches:
          - main
    jobs:
      unit_tests:
        name: Run .NET unit tests
        runs-on: windows-latest
        steps:
          - name: Checkout (GitHub)
            uses: actions/checkout@v3
          - name: Start Azure Cosmos DB emulator
            run: |
              Write-Host "Launching Cosmos DB Emulator"
              Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator"
              Start-CosmosDbEmulator
          - name: Run .NET tests
            run: dotnet test
    

    注意

    使用各种参数或 PowerShell 命令从命令行启动模拟器。 有关详细信息,请参阅 模拟器命令行参数

后续步骤