本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 Amazon DynamoDB NoSQL 数据库
注意
这些主题中的编程模型同时存在于 .NET Framework 和 .NET (Core) 中,但是调用约定不同,无论是同步还是异步。
AWS SDK for .NET支持 Amazon DynamoDB,这是一项由 AWS 提供的快速 NoSQL 数据库服务。开发工具包为与 DynamoDB 通信提供了三种编程模型:低级模型、文档模型和对象持久性模型。
以下信息介绍了这些模型及其 API,提供有关使用方式和使用时机的示例,并向您提供AWS SDK for .NET中额外 DynamoDB 编程资源的链接。
低级模型
低级编程模型封装对 DynamoDB 服务的直接调用。您可以通过 Amazon.DynamoDBv2 命名空间访问此模型。
在三种模型中,低级模型需要编写的代码最多。例如,您必须将 .NET 数据类型转换为 DynamoDB 中的对等类型。但是,此模型向您提供了对大部分功能的访问。
以下示例显示如何使用低级模型创建表、修改表以及将项目插入到 DynamoDB 中的表。
创建表
在以下示例中,您可以使用 CreateTable
类的 AmazonDynamoDBClient
方法创建表。CreateTable
方法使用包含特性的 CreateTableRequest
类的实例,例如必需的项目属性名称、主键定义和吞吐容量。该 CreateTable
方法返回 CreateTableResponse
类的实例。
// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); Console.WriteLine("Getting list of tables"); List<string> currentTables = client.ListTables().TableNames; Console.WriteLine("Number of tables: " + currentTables.Count); if (!currentTables.Contains("AnimalsInventory")) { var request = new CreateTableRequest { TableName = "AnimalsInventory", AttributeDefinitions = new List<AttributeDefinition> { new AttributeDefinition { AttributeName = "Id", // "S" = string, "N" = number, and so on. AttributeType = "N" }, new AttributeDefinition { AttributeName = "Type", AttributeType = "S" } }, KeySchema = new List<KeySchemaElement> { new KeySchemaElement { AttributeName = "Id", // "HASH" = hash key, "RANGE" = range key. KeyType = "HASH" }, new KeySchemaElement { AttributeName = "Type", KeyType = "RANGE" }, }, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 10, WriteCapacityUnits = 5 }, }; var response = client.CreateTable(request); Console.WriteLine("Table created with request ID: " + response.ResponseMetadata.RequestId); }
验证该表已准备好修改
您必须先准备好表进行修改,然后才能更改或修改表。以下示例显示了如何使用低级模型验证 DynamoDB 中的表已准备就绪。在此示例中,通过 DescribeTable
类的 AmazonDynamoDBClient
方法引用要检查的目标表。该代码每五秒检查一次表的 TableStatus
属性的值。当状态设置为 ACTIVE
时,表已准备好供修改。
// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); var status = ""; do { // Wait 5 seconds before checking (again). System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); try { var response = client.DescribeTable(new DescribeTableRequest { TableName = "AnimalsInventory" }); Console.WriteLine("Table = {0}, Status = {1}", response.Table.TableName, response.Table.TableStatus); status = response.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. } } while (status != TableStatus.ACTIVE);
将项目插入到表中
在以下示例中,您使用低级模型将两个项目插入到 DynamoDB 中的表。每个项目通过 PutItem
类的 AmazonDynamoDBClient
方法插入,使用 PutItemRequest
类的实例。PutItemRequest
类的两个实例中的每个实例都接受将要插入项目的表名以及一系列项目属性值。
// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); var request1 = new PutItemRequest { TableName = "AnimalsInventory", Item = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { N = "1" }}, { "Type", new AttributeValue { S = "Dog" }}, { "Name", new AttributeValue { S = "Fido" }} } }; var request2 = new PutItemRequest { TableName = "AnimalsInventory", Item = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { N = "2" }}, { "Type", new AttributeValue { S = "Cat" }}, { "Name", new AttributeValue { S = "Patches" }} } }; client.PutItem(request1); client.PutItem(request2);
文档模型
文档编程模型提供了一种更简单的方法来处理 DynamoDB 中的数据。此模型专门用于访问表和表中的项目。您可以通过 Amazon.DynamoDBv2.DocumentModel 命名空间访问此模型。
与低级编程模型相比,使用文档模型更容易针对 DynamoDB 数据编写代码。例如,您无需将相同数量的 .NET 数据类型转换为 DynamoDB 中的对等类型。不过,使用此模型所能访问的功能没有低级编程模型所提供的多。例如,您可以使用此模型创建、检索、更新和删除表中的项目。但是,要创建表,您必须使用低级模型。与对象持久化模型相比,此模型需要编写更多代码来存储、加载和查询 .NET 对象。
有关 DynamoDB 文档编程模型的更多信息,请参阅 Amazon DynamoDB 开发人员指南中的 .NET:文档模型。
以下各节提供有关如何创建所需的 DynamoDB 表的表示形式的信息,以及如何使用文档模型将项目插入表和从表中获取项目的示例。
创建表的表示形式
要使用文档模型执行数据操作,您必须首先创建 Table
类的实例,它会代表特定的表。有两种主要方式可执行此操作:
LoadTable 方法
第一种机制是使用 Table
类的静态 LoadTable
方法之一,类似于以下示例:
var client = new AmazonDynamoDBClient(); Table table = Table.LoadTable(client, "Reply");
注意
虽然这种机制起作用,但在某些条件下,由于冷启动和线程池行为,它有时会导致额外的延迟或死锁。有关这些行为的更多信息,请参阅博客文章 Improved DynamoDB Initialization Patterns for the AWS SDK for .NET
TableBuilder
在 AWSSDK.DynamoDBv2 NuGet 程序包的 3.7.203 版本TableBuilder
类。该机制可以通过删除某些隐式方法调用(特别是 DescribeTable
方法)来解决上述行为。此机制的使用方式类似于以下示例:
var client = new AmazonDynamoDBClient(); var table = new TableBuilder(client, "Reply") .AddHashKey("Id", DynamoDBEntryType.String) .AddRangeKey("ReplyDateTime", DynamoDBEntryType.String) .AddGlobalSecondaryIndex("PostedBy-Message-index", "Author", DynamoDBEntryType.String, "Message", DynamoDBEntryType.String) .Build();
有关此替代机制的更多信息,请再次参阅博客文章 Improved DynamoDB Initialization Patterns for the AWS SDK for .NET
将项目插入到表中
在以下示例中,回复通过 Table
类的 PutItemAsync
方法插入到 Reply 表中。PutItemAsync
方法获取 Document
类的实例;Document
类只是已初始化属性的集合。
using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DocumentModel; // Create a representation of the "Reply" table // by using one of the mechanisms described previously. // Then, add a reply to the table. var newReply = new Document(); newReply["Id"] = Guid.NewGuid().ToString(); newReply["ReplyDateTime"] = DateTime.UtcNow; newReply["PostedBy"] = "Author1"; newReply["Message"] = "Thank you!"; await table.PutItemAsync(newReply);
从表中获取项目
在以下示例中,通过 Table
类的 GetItemAsync
方法检索回复。为确定要获取的回复,GetItemAsync
方法使用目标回复的 hash-and-range 主键。
using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DocumentModel; // Create a representation of the "Reply" table // by using one of the mechanisms described previously. // Then, get a reply from the table // where "guid" is the hash key and "datetime" is the range key. var reply = await table.GetItemAsync(guid, datetime); Console.WriteLine("Id = " + reply["Id"]); Console.WriteLine("ReplyDateTime = " + reply["ReplyDateTime"]); Console.WriteLine("PostedBy = " + reply["PostedBy"]); Console.WriteLine("Message = " + reply["Message"]);
前面的示例为 WriteLine
方法隐式将表值转换为字符串。您可以使用 DynamoDBEntry
类的多种“As[type]”方法执行显式转换。例如,对于 Id
的值,您可以通过 AsGuid()
方法将其从 Primitive
数据类型显式转换为 GUID:
var guid = reply["Id"].AsGuid();
对象持久化模型
对象持久性编程模型专门针对在 DynamoDB 中存储、加载和查询 .NET 对象而设计。您可以通过 Amazon.DynamoDBv2.DataModel 命名空间访问此模型。
在三种模型中,使用对象持久性模型最容易针对要存储、加载或查询的 DynamoDB 数据编写代码。例如,您可以直接使用 DynamoDB 数据类型。但是,此模型仅支持在 DynamoDB 中存储、加载和查询 .NET 对象的操作。例如,您可以使用此模型创建、检索、更新和删除表中的项目。不过,您必须先使用低级模型创建表,然后使用此模型将 .NET 类映射到表。
有关 DynamoDB 对象持久性编程模型的更多信息,请参阅 Amazon DynamoDB 开发人员指南中的 .NET:对象持久性模型。
以下示例向您演示如何定义表示 DynamoDB 项目的 .NET 类,使用 .NET 类的实例将项目插入到 DynamoDB ,以及使用 .NET 对象的实例从表获取项目。
定义表示表中项目的 .NET 类
在以下类定义示例中,DynamoDBTable
属性指定表名,而 DynamoDBHashKey
和 DynamoDBRangeKey
属性对表的 hash-and-range 主键进行建模。定义 DynamoDBGlobalSecondaryIndexHashKey
属性的目的是为了可以构造对特定作者回复的查询。
using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; [DynamoDBTable("Reply")] public class Reply { [DynamoDBHashKey] public string Id { get; set; } [DynamoDBRangeKey(StoreAsEpoch = false)] public DateTime ReplyDateTime { get; set; } [DynamoDBGlobalSecondaryIndexHashKey("PostedBy-Message-Index", AttributeName ="PostedBy")] public string Author { get; set; } [DynamoDBGlobalSecondaryIndexRangeKey("PostedBy-Message-Index")] public string Message { get; set; } }
为对象持久性模型创建上下文
要使用适用于 DynamoDB 的对象持久性编程模型,您需要创建一个上下文,它提供到 DynamoDB 的连接,让您能够访问表、执行各种操作,以及执行查询。
基本上下文
以下代码示例演示如何创建最基本的上下文 。
using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client);
具有 DisableFetchingTableMetadata 属性的上下文
以下示例显示了如何额外设置 DynamoDBContextConfig
类的 DisableFetchingTableMetadata
属性以防止隐式调用 DescribeTable
方法。
using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client, new DynamoDBContextConfig { DisableFetchingTableMetadata = true });
如果将该 DisableFetchingTableMetadata
属性设置为 false
(默认值),如第一个示例所示,则可以省略 Reply
类中描述表项键和索引结构的属性。相反,这些属性将通过对 DescribeTable
方法的隐式调用推断出来。如第二个示例所示,如果 DisableFetchingTableMetadata
设置为 true
,则对象持久性模型的方法(例如 SaveAsync
和 QueryAsync
)完全依赖于 Reply
类中定义的属性。在这种情况下,不会调用 DescribeTable
方法。
注意
在某些情况下,由于冷启动和线程池行为,对 DescribeTable
方法的调用有时会导致额外的延迟或死锁。因此,有时避免调用该方法是有利的。
有关这些行为的更多信息,请参阅博客文章 Improved DynamoDB Initialization Patterns for the AWS SDK for .NET
使用 .NET 类的实例将项目插入到表中
在本示例中,项目通过 SaveAsync
类的 DynamoDBContext
方法插入,该方法采用表示项目的 .NET 类的已初始化实例。
using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; // Create an appropriate context for the object persistence programming model, // examples of which have been described earlier. // Create an object that represents the new item. var reply = new Reply() { Id = Guid.NewGuid().ToString(), ReplyDateTime = DateTime.UtcNow, Author = "Author1", Message = "Thank you!" }; // Insert the item into the table. await context.SaveAsync<Reply>(reply, new DynamoDBOperationConfig { IndexName = "PostedBy-Message-index" });
使用 .NET 类的实例从表中获取项目
在此示例中,使用 DynamoDBContext
类的 QueryAsync
方法创建了一个查询,用于查找“Author1”的所有记录。然后,通过查询的 GetNextSetAsync
方法检索项目。
using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; // Create an appropriate context for the object persistence programming model, // examples of which have been described earlier. // Construct a query that finds all replies by a specific author. var query = context.QueryAsync<Reply>("Author1", new DynamoDBOperationConfig { IndexName = "PostedBy-Message-index" }); // Display the result. var set = await query.GetNextSetAsync(); foreach (var item in set) { Console.WriteLine("Id = " + item.Id); Console.WriteLine("ReplyDateTime = " + item.ReplyDateTime); Console.WriteLine("PostedBy = " + item.Author); Console.WriteLine("Message = " + item.Message); }
有关对象持久性模型的其它信息
上面显示的示例和解释有时包括名为 DisableFetchingTableMetadata
的 DynamoDBContext
类的属性。此属性在 AWSSDK.DynamoDBv2 NuGet 程序包的 3.7.203 版本
以下是有关此属性的一些其它信息。
-
如果您使用.NET Framework,则可以在
app.config
或web.config
文件中全局设置此属性。 -
可以使用
AWSConfigsDynamoDB
类全局设置此属性,如下面的示例所示。// Set the DisableFetchingTableMetadata property globally // before constructing any context objects. AWSConfigsDynamoDB.Context.DisableFetchingTableMetadata = true; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client);
-
在某些情况下,您无法将 DynamoDB 属性添加到 .NET 类中;例如,如果该类是在依赖项中定义的。在这种情况下,仍然可以利用
DisableFetchingTableMetadata
属性。为此,除了DisableFetchingTableMetadata
属性之外,还要使用TableBuilder
类。在 AWSSDK.DynamoDBv2 NuGet 程序包的 3.7.203 版本中引入了 TableBuilder
类。// Set the DisableFetchingTableMetadata property globally // before constructing any context objects. AWSConfigsDynamoDB.Context.DisableFetchingTableMetadata = true; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client); var table = new TableBuilder(client, "Reply") .AddHashKey("Id", DynamoDBEntryType.String) .AddRangeKey("ReplyDateTime", DynamoDBEntryType.String) .AddGlobalSecondaryIndex("PostedBy-Message-index", "Author", DynamoDBEntryType.String, "Message", DynamoDBEntryType.String) .Build(); // This registers the "Reply" table we constructed via the builder. context.RegisterTableDefinition(table); // Now operations like this will work, // even if the Reply class was not annotated with this index. var query = context.QueryAsync<Reply>("Author1", new DynamoDBOperationConfig() { IndexName = "PostedBy-Message-index" });
更多信息
使用AWS SDK for .NET编程 DynamoDB 信息和示例**
低级模型信息和示例
文档模型信息和示例
对象持久性模型信息和示例