Persistence Model with AWS DynamoDB

Written by Lawrence Botley

A simple C# step by step tutorial for the AWS DynamoDB persistence model framework

DynamoDB is a fast and scalable NoSQL database service provided by Amazon Web Services. The Amazon SDK provide two methods to access the service, this tutorial focuses on the persistent storage model.

Configuring the Amazon DynamoDB project

  1. Insert your AWS access key
  2. Insert you AWS Secret key
  3. Create an empty dynamoDB table called "Dinosaur"
  4. Enter the region URL of your table: for example "http://dynamodb.us-west-1.amazonaws.com"
<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="AWSAccessKey" value="INSERT ACCESS KEY"/>
    <add key="AWSSecretKey" value="INSERT SECRET KEY"/>
    <add key="ServiceURL" value="http://dynamodb.us-west-1.amazonaws.com"/>
  </appSettings>
</configuration>

Persistence Model with Amazon DynamoDB

DynamoDB objects can be mapped to a class by Attributes. This way properties can be automatically cast to and from a convertible data-type in DynamoDb. Today we are going to be storing Dinosaurs in the cloud with 5 Attributes:

  1. [DynamoDBTable("Dinosaur")] - Flags the class as a DynamoDb Table
  2. [DynamoDBHashKey] - The primary hash key property
  3. [DynamoDBProperty(AttributeName = "Name")] - Flags a property and allows an alternate name other than the C# property name
  4. [DynamoDBProperty(AttributeName = "Photo", Converter = typeof(ImageConverter))] - A custom binary data type converter to store images as binary blobs

using System;
using System.Drawing;
using Amazon.DynamoDB.DataModel
using System.Collections.Generic;

namespace DynamoDb
{
    [DynamoDBTable("Dinosaur")]
    public class Dinosaur
    {
        [DynamoDBHashKey]
        public string Id { get; set; }

        [DynamoDBProperty(AttributeName = "Name")]
        public string Name { get; set; }

        [DynamoDBProperty(AttributeName = "HeightMetres")]
        public double HeightMetres { get; set; }

        [DynamoDBProperty(AttributeName = "WeightKG")]
        public double WeightKg { get; set; }

        [DynamoDBProperty(AttributeName = "Age")]
        public int Age { get; set; }

        [DynamoDBProperty(AttributeName = "Characteristics")]
        public List<string> Characteristics { get; set; }

        [DynamoDBProperty(AttributeName = "Photo", Converter = typeof(ImageConverter))]
        public Image Photo { get; set; }

        [DynamoDBIgnore]
        public int IgnoreMe { get; set; }
    }
}

Return, insert, update, and delete in Amazon DynamoDB

Return an object from storage using the primary hash key id

        public static Dinosaur GetDinosaur(string id)
        {
            var context = new DynamoDBContext(amazonDynamoDbClient);
            var dinosaur = context.Load<Dinosaur>(id);
            if(dinosaur==null)
                throw new Exception("There is no dinosaur with that Id");

            return dinosaur;
        }

Create a new object in storage. The example uses the data-types string, integer, double, List<string>, Image

        public static void NewDinosaur()
        {
            var context = new DynamoDBContext(amazonDynamoDbClient);

            var dinosaur = new Dinosaur
            {
                Id = "1",
                HeightMetres = 4,
                WeightKg = 7000,
                Age = 65000000,
                Name = "T-Rex",
                Characteristics = new List<string>(){ "Hungry", "Scary", "Loud", "Lonely", "Sneaky" },
                Photo = GetImage()
            };

            context.Save(dinosaur);
        }

Update an object from storage using the hash key id

 
        public static void UpdateDinosaur()
        {
            var context = new DynamoDBContext(amazonDynamoDbClient);
            var dinosaur = context.Load<Dinosaur>("1");
            dinosaur.Age = 65000001;
            dinosaur.HeightMetres = 4.5;
            dinosaur.WeightKg = 7500;

            context.Save(dinosaur);
        }

Delete an object from storage using the hash key id

        public static void DeleteDinosaur(string id)
        {
            var context = new DynamoDBContext(amazonDynamoDbClient);
            var dinosaur = GetDinosaur(id);

            context.Delete(dinosaur);
        }

Storing .net images as blobs in DynamoDB

The ImageConverter class allows the storage of .NET image objects and implements the IPropertyConverter class and employs two methods that are calls when the object requires serialization or de-serialization. 

You can create your own IPropertyConverter as long as they implement to FromEntry and ToEntry methods.

using System.Drawing;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using Amazon.DynamoDB.DataModel;
using Amazon.DynamoDB.DocumentModel;
 
namespace DynamoDb
{
    public class ImageConverter : IPropertyConverter
    {
        public object FromEntry(DynamoDBEntry entry)
        {
            var ms = new MemoryStream(entry.AsByteArray());
            var image = Image.FromStream(ms);
            return image;
        }
 
        public DynamoDBEntry ToEntry(object value)
        {
            var image = value as Image;
            if (image == null) return new Primitive { Value = null };
 
            var ms = new MemoryStream();
            image.Save(ms, ImageFormat.Jpeg);
 
            DynamoDBEntry entry = new Primitive
            {
                Value = ms.ToArray(),
                Type = DynamoDBEntryType.Binary
            };
            return entry;
        }
    }
}

So there you have it!

© 2016 RK Consulting. All rights reserved.