Amazon DynamoDB
入门指南 (API Version 2012-08-10)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。点 击 Getting Started with Amazon AWS to see specific differences applicable to the China (Beijing) Region.

步骤 3:创建、读取、更新和删除项目

在此步骤中,您将对 Movies 表中的项目执行读写操作。

要了解有关数据读写的更多信息,请参阅 Amazon DynamoDB 开发人员指南 中的处理项目

步骤 3.1:创建新项目

在此步骤中,您将向 Movies 表中添加一个新项目。

  1. 将以下程序复制到 Program.cs 文件中,替代其当前内容。

    Copy
    using System; using System.Collections.Generic; using System.Linq; using System.Text; using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get a Table object for the table that you created in Step 1 Table table = GetTableObject("Movies"); if (table == null) { PauseForDebugWindow(); return; } // Create a Document representing the movie item to be written to the table Document document = new Document(); document["year"] = 2015; document["title"] = "The Big New Movie"; document["info"] = Document.FromJson("{\"plot\" : \"Nothing happens at all.\",\"rating\" : 0}"); // Use Table.PutItem to write the document item to the table try { table.PutItem(document); Console.WriteLine("\nPutItem succeeded.\n"); } catch (Exception ex) { Console.WriteLine("\n Error: Table.PutItem failed because: " + ex.Message); PauseForDebugWindow(); return; } } public static Table GetTableObject(string tableName) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } // Now, create a Table object for the specified table Table table = null; try { table = Table.LoadTable(client, tableName); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return (null); } return (table); } public static void PauseForDebugWindow() { // Keep the console open if in Debug mode... Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); Console.WriteLine(); } } }

    注意

    主键是必填项。在此表中,主键由分区键属性 (year) 和排序键属性 (title) 组合而成。

    此代码向表中写入一个项目,其中包含两个主键属性 (year + title) 和一个存储有关电影的更多信息的复杂 info 属性。

  2. 编译并运行程序。

步骤 3.2:读取项目

在上一个程序中,您已向表中添加了以下项目:

Copy
{ year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } }

您可以使用 GetItem 方法读取 Movies 表中的项目。您必须指定主键值,以便在知道 Movies 中的任何项目的 yeartitle 的情况下读取该项目。

  1. 将以下程序复制到 Program.cs 文件中,替代其当前内容。

    Copy
    using System; using System.Collections.Generic; using System.Linq; using System.Text; using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get a Table object for the table that you created in Step 1 Table table = GetTableObject("Movies"); if (table == null) { PauseForDebugWindow(); return; } try { Document document = table.GetItem(2015, "The Big New Movie"); if (document != null) Console.WriteLine("\nGetItem succeeded: \n" + document.ToJsonPretty()); else Console.WriteLine("\nGetItem succeeded, but the item was not found"); } catch (Exception e) { Console.WriteLine(e.Message); } } public static Table GetTableObject(string tableName) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } // Now, create a Table object for the specified table Table table = null; try { table = Table.LoadTable(client, tableName); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return (null); } return (table); } public static void PauseForDebugWindow() { // Keep the console open if in Debug mode... Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); Console.WriteLine(); } } }
  2. 编译并运行程序。

步骤 3.3:更新项目

您可以使用 UpdateItem 方法修改现有项目。您可以更新现有属性的值、添加新属性或删除属性。

在此示例中,您可以执行以下更新:

  • 更改现有属性 (ratingplot) 的值。

  • 向现有 info 映射中添加新的列表属性 (actors)。

项目将在以下基础上进行更改:

Copy
{ year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } }

更改为以下项目:

Copy
{ year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } }
  1. 将以下程序复制到 Program.cs 文件中,替代其当前内容。

    Copy
    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get an AmazonDynamoDBClient for the local database AmazonDynamoDBClient client = GetLocalClient(); if (client == null) { PauseForDebugWindow(); return; } // Create an UpdateItemRequest to modify two existing nested attributes // and add a new one UpdateItemRequest updateRequest = new UpdateItemRequest() { TableName = "Movies", Key = new Dictionary<string, AttributeValue> { { "year", new AttributeValue { N = "2015" } }, { "title", new AttributeValue { S = "The Big New Movie" }} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":r", new AttributeValue { N = "5.5" } }, { ":p", new AttributeValue { S = "Everything happens all at once!" } }, { ":a", new AttributeValue { SS = { "Larry","Moe","Curly" } } } }, UpdateExpression = "SET info.rating = :r, info.plot = :p, info.actors = :a", ReturnValues = "UPDATED_NEW" }; // Use AmazonDynamoDBClient.UpdateItem to update the specified attributes UpdateItemResponse uir = null; try { uir = client.UpdateItem(updateRequest); } catch (Exception ex) { Console.WriteLine("\nError: UpdateItem failed, because: " + ex.Message); if (uir != null) Console.WriteLine(" Status code was " + uir.HttpStatusCode.ToString()); PauseForDebugWindow(); return; } // Get the item from the table and display it to validate that the update succeeded DisplayMovieItem(client, "2015", "The Big New Movie"); } public static AmazonDynamoDBClient GetLocalClient() { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } return (client); } public static void DisplayMovieItem(AmazonDynamoDBClient client, string year, string title) { // Create Primitives for the HASH and RANGE portions of the primary key Primitive hash = new Primitive(year, true); Primitive range = new Primitive(title, false); Table table = null; try { table = Table.LoadTable(client, "Movies"); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return; } Document document = table.GetItem(hash, range); Console.WriteLine("\n The movie record looks like this: \n" + document.ToJsonPretty()); } public static void PauseForDebugWindow() { // Keep the console open if in Debug mode... Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); Console.WriteLine(); } } }

    注意

    由于 适用于 .NET 的 AWS 开发工具包 中的文档模型不支持更新嵌套属性,因此我们需要使用 AmazonDynamoDBClient.UpdateItem API (而非 Table.UpdateItem) 更新顶级 info 属性下的属性。

    要执行此操作,我们需创建 UpdateItemRequest,以指定我们要更新的项目和要设置的新值。

    • UpdateExpression 定义了要对指定项目执行的所有更新。

    • 通过将 ReturnValues 字段设置为 "UPDATED_NEW",我们将请求 DynamoDB 在响应正文中仅返回更新后的属性。

  2. 编译并运行程序。

步骤 3.4:递增一个原子计数器

DynamoDB 支持原子计数器,以便您使用 UpdateItem 方法来递增或递减现有属性的值,而不干扰其他写入请求 (所有写入请求的应用顺序跟接收顺序相同)。

以下程序将递增电影的 rating。每次运行此程序时,此属性都会递增 1。同样,UpdateExpression 将决定发生的情况:

Copy
UpdateExpression = "SET info.rating = info.rating + :inc",
  1. 将以下程序复制到 Program.cs 文件中,替代其当前内容。

    Copy
    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get an AmazonDynamoDBClient for the local database AmazonDynamoDBClient client = GetLocalClient(); if (client == null) { PauseForDebugWindow(); return; } // Create an UpdateItemRequest to modify two existing nested attributes // and add a new one UpdateItemRequest updateRequest = new UpdateItemRequest() { TableName = "Movies", Key = new Dictionary<string, AttributeValue> { { "year", new AttributeValue { N = "2015" } }, { "title", new AttributeValue { S = "The Big New Movie" }} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":inc", new AttributeValue { N = "1" } } }, UpdateExpression = "SET info.rating = info.rating + :inc", ReturnValues = "UPDATED_NEW" }; // Use AmazonDynamoDBClient.UpdateItem to update the specified attributes UpdateItemResponse uir = null; try { uir = client.UpdateItem(updateRequest); } catch (Exception ex) { Console.WriteLine("\nError: UpdateItem failed, because " + ex.Message); if (uir != null) Console.WriteLine(" Status code was: " + uir.HttpStatusCode.ToString()); PauseForDebugWindow(); return; } // Get the item from the table and display it to validate that the update succeeded DisplayMovieItem(client, "2015", "The Big New Movie"); } public static AmazonDynamoDBClient GetLocalClient() { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } return (client); } public static void DisplayMovieItem(AmazonDynamoDBClient client, string year, string title) { // Create Primitives for the HASH and RANGE portions of the primary key Primitive hash = new Primitive(year, true); Primitive range = new Primitive(title, false); Table table = null; try { table = Table.LoadTable(client, "Movies"); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return; } Document document = table.GetItem(hash, range); Console.WriteLine("\n The movie record looks like this: \n" + document.ToJsonPretty()); } public static void PauseForDebugWindow() { // Keep the console open if in Debug mode... Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); Console.WriteLine(); } } }
  2. 编译并运行程序。

步骤 3.5:更新项目 (有条件)

以下程序演示了如何使用有条件的 UpdateItem。如果条件为真,则更新成功;否则,不执行更新。

在此示例中,仅当有超过 3 位男演员时,才会更新项目。

  1. 将以下程序复制到 Program.cs 文件中,替代其当前内容。

    Copy
    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get an AmazonDynamoDBClient for the local database AmazonDynamoDBClient client = GetLocalClient(); if (client == null) { PauseForDebugWindow(); return; } // Create an UpdateItemRequest to modify two existing nested attributes // and add a new one UpdateItemRequest updateRequest = new UpdateItemRequest() { TableName = "Movies", Key = new Dictionary<string, AttributeValue> { { "year", new AttributeValue { N = "2015" } }, { "title", new AttributeValue { S = "The Big New Movie" } } }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":n", new AttributeValue { N = "3" } } }, ConditionExpression = "size(info.actors) > :n", UpdateExpression = "REMOVE info.actors", ReturnValues = "UPDATED_NEW" }; // Use AmazonDynamoDBClient.UpdateItem to update the specified attributes UpdateItemResponse uir = null; try { uir = client.UpdateItem(updateRequest); } catch (Exception ex) { Console.WriteLine("\nError: UpdateItem failed, because:\n " + ex.Message); if (uir != null) Console.WriteLine(" Status code was " + uir.HttpStatusCode.ToString()); PauseForDebugWindow(); return; } if (uir.HttpStatusCode != System.Net.HttpStatusCode.OK) { PauseForDebugWindow(); return; } // Get the item from the table and display it to validate that the update succeeded DisplayMovieItem(client, "2015", "The Big New Movie"); } public static AmazonDynamoDBClient GetLocalClient() { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } return (client); } public static void DisplayMovieItem(AmazonDynamoDBClient client, string year, string title) { // Create Primitives for the HASH and RANGE portions of the primary key Primitive hash = new Primitive(year, true); Primitive range = new Primitive(title, false); Table table = null; try { table = Table.LoadTable(client, "Movies"); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return; } Document document = table.GetItem(hash, range); Console.WriteLine("\n The movie record looks like this: \n" + document.ToJsonPretty()); } public static void PauseForDebugWindow() { // Keep the console open if in Debug mode... Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); Console.WriteLine(); } } }
  2. 编译并运行程序。

    程序应该会失败并显示以下消息:

    The conditional request failed

    这是因为电影包含三位男演员,但此条件是检查男演员数量是否大于 3。

  3. 修改程序,以使 ConditionExpression 使用的男演员数量为 2,而非 3:

    Copy
    { ":n", new AttributeValue { N = "2" } }

    现在,此条件指定男演员的数量必须大于 2。

  4. 现在您编译和运行程序时,UpdateItem 操作应该会成功。

步骤 3.6:删除项目

您可以执行 Table.DeleteItem 操作,通过指定项目的主键来删除一个项目。您可以在 DeleteItemOperationConfig 参数中提供一个条件,避免在不符合条件时删除项目。

在以下示例中,您将尝试删除评分为 5 分或更低的特定电影项目。

  1. 将以下程序复制到 Program.cs 文件中,替代其当前内容。

    Copy
    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get a Table object for the table that you created in Step 1 Table table = GetTableObject("Movies"); if (table == null) return; // Create the condition DeleteItemOperationConfig opConfig = new DeleteItemOperationConfig(); lopConfig.ConditionalExpression = new Expression(); opConfig.ConditionalExpression.ExpressionAttributeValues[":val"] = "5.0"; opConfig.ConditionalExpression.ExpressionStatement = "info.rating <= :val"; // Delete this item try { table.DeleteItem(2015, "The Big New Movie", opConfig); } catch (Exception ex) { Console.WriteLine("\n Error: Could not delete the movie item with year={0}, title=\"{1}\"\n Reason: {2}.", 2015, "The Big New Movie", ex.Message); } // Try to retrieve it, to see if it has been deleted Document document = table.GetItem(2015, "The Big New Movie"); if (document == null) Console.WriteLine("\n The movie item with year={0}, title=\"{1}\" has been deleted.", 2015, "The Big New Movie"); else Console.WriteLine("\nRead back the item: \n" + document.ToJsonPretty()); // Keep the console open if in Debug mode... Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); Console.WriteLine(); } public static Table GetTableObject(string tableName) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } // Now, create a Table object for the specified table Table table = null; try { table = Table.LoadTable(client, tableName); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return (null); } return (table); } } }
  2. 编译并运行程序。

    程序应该会失败并显示以下消息:

    The conditional request failed

    这是因为此特定电影的评分大于 5 分。

  3. 修改程序,从 table.DeleteItem 调用中删除名为 opConfigDeleteItemOperationConfig

    Copy
    try { table.DeleteItem( 2015, "The Big New Movie" ); }
  4. 编译并运行程序。因为您已移除条件,所以此时删除操作将会成功。