Skip to main content

Quick Start

Get up and running with FluentDynamoDB in minutes.

Define an Entity

Create a C# class that maps to your DynamoDB table. The class must be partial to allow the source generator to add mapping code.

using Oproto.FluentDynamoDb.Attributes;

// The class MUST be partial - the source generator adds mapping code
[DynamoDbTable("users")]
public partial class User
{
// PartitionKey marks this property as the table's partition key
// DynamoDbAttribute maps the property to the DynamoDB attribute name "pk"
[PartitionKey]
[DynamoDbAttribute("pk")]
public string UserId { get; set; } = string.Empty;

// Optional: SortKey for composite primary keys
// [SortKey]
// [DynamoDbAttribute("sk")]
// public string SortKey { get; set; } = string.Empty;

// Map each property to its DynamoDB attribute name
[DynamoDbAttribute("email")]
public string Email { get; set; } = string.Empty;

[DynamoDbAttribute("name")]
public string Name { get; set; } = string.Empty;

[DynamoDbAttribute("status")]
public string Status { get; set; } = "active";

[DynamoDbAttribute("created_at")]
public DateTime CreatedAt { get; set; }
}

Key Points:

  • partial class is required for source generation
  • Exactly one [PartitionKey] property is required
  • [DynamoDbAttribute] maps properties to DynamoDB attribute names
  • [SortKey] is optional for tables with composite keys

Create a Table Instance

The source generator creates a typed table class for your entity. Instantiate it with a DynamoDB client.

using Amazon.DynamoDBv2;

var client = new AmazonDynamoDBClient();

// Basic instantiation - uses default settings
var table = new UsersTable(client, "users");

With Configuration Options

Use FluentDynamoDbOptions to configure logging and other features:

using Microsoft.Extensions.Logging;
using Oproto.FluentDynamoDb;
using Oproto.FluentDynamoDb.Logging;

// Create options with logging enabled
var options = new FluentDynamoDbOptions()
.WithLogger(loggerFactory.ToDynamoDbLogger<UsersTable>());

var table = new UsersTable(client, "users", options);

Basic Operations

The library provides express-route methods for simple operations. Use the entity accessor (table.Users) for cleaner, type-safe code.

Create (Put)

var user = new User
{
UserId = "user123",
Email = "user@example.com",
Name = "John Doe",
CreatedAt = DateTime.UtcNow
};

// Express-route - simplest approach
await table.Users.PutAsync(user);

Read (Get)

// Express-route - returns the entity directly
var user = await table.Users.GetAsync("user123");

if (user != null)
{
Console.WriteLine($"Found user: {user.Name}");
}

Update

Use lambda expressions for type-safe, readable updates:

// Lambda expression - type-safe with IntelliSense
await table.Users.Update("user123")
.Set(x => new { Name = "Jane Doe" })
.UpdateAsync();

Delete

// Express-route delete
await table.Users.DeleteAsync("user123");

Query Data

Query items using lambda expressions for type-safe queries:

// Lambda expression query - type-safe with IntelliSense
var users = await table.Users.Query()
.Where(x => x.UserId == "user123")
.ToListAsync();

foreach (var user in users)
{
Console.WriteLine($"User: {user.Name}, Email: {user.Email}");
}

Conditional Query Example

Add conditions to filter results:

// Query with additional conditions
var activeUsers = await table.Users.Query()
.Where(x => x.UserId == "user123" && x.Status == "active")
.ToListAsync();

Next Steps