C# Database Client
The TerraScale Database Client provides a strongly-typed, high-performance SDK for C# and .NET applications.
Installation
Section titled “Installation”dotnet add package TerraScale.Database.ClientConfiguration
Section titled “Configuration”Basic Configuration
Section titled “Basic Configuration”using TerraScale.Database.Client;using TerraScale.Database.Client.Configuration;
var options = new TerraScaleDatabaseOptions{ ApiKey = "ts_live_your_api_key", Endpoint = "https://api.terrascale.io", Region = "us-east-1", DefaultDatabase = "my-database", Timeout = TimeSpan.FromSeconds(30), Retry = new RetryPolicyOptions { MaxRetries = 3, BaseDelay = TimeSpan.FromMilliseconds(500), MaxDelay = TimeSpan.FromSeconds(10), UseJitter = true }};
var client = new TerraScaleDatabase(options);Configuration Options
Section titled “Configuration Options”| Option | Type | Default | Description |
|---|---|---|---|
ApiKey | string | Required | Your API key |
Endpoint | string | Required | API endpoint URL |
Region | string | "us-east-1" | Default region |
DefaultDatabase | string | null | Default database ID |
Timeout | TimeSpan | 30 seconds | HTTP request timeout |
Retry.MaxRetries | int | 3 | Max retry attempts |
Retry.BaseDelay | TimeSpan | 500ms | Initial retry delay |
Retry.MaxDelay | TimeSpan | 10 seconds | Maximum retry delay |
Retry.UseJitter | bool | true | Add randomness to delays |
Builder Pattern
Section titled “Builder Pattern”var client = TerraScaleDatabase.Create(options => options .WithApiKey("ts_live_your_api_key") .WithEndpoint("https://api.terrascale.io") .WithDefaultDatabase("my-database") .WithTimeout(TimeSpan.FromSeconds(60)) .WithRetry(retry => retry .MaxRetries(5) .BaseDelay(TimeSpan.FromSeconds(1)) ));Item Operations
Section titled “Item Operations”Put Item
Section titled “Put Item”var item = new DatabaseItem{ PartitionKey = "user#123", SortKey = "profile", Attributes = new Dictionary<string, object?> { ["name"] = "John Doe", ["email"] = "john@example.com", ["age"] = 30, ["tags"] = new[] { "premium", "verified" } }};
var result = await client.PutItemAsync(item);
if (result.IsSuccess){ Console.WriteLine("Item saved!");}else{ Console.WriteLine($"Error: {result.Errors.First().Message}");}Get Item
Section titled “Get Item”// Get by partition key onlyvar result = await client.GetItemAsync("user#123");
// Get by partition key and sort keyvar result = await client.GetItemAsync("user#123", "profile");
if (result.IsSuccess){ var item = result.Value; var name = item.GetAttribute<string>("name"); var age = item.GetAttribute<int>("age", defaultValue: 0); Console.WriteLine($"User: \{name\}, Age: {age}");}Delete Item
Section titled “Delete Item”var result = await client.DeleteItemAsync("user#123", "profile");
if (result.IsSuccess){ Console.WriteLine("Item deleted!");}Query Operations
Section titled “Query Operations”Query with Filter
Section titled “Query with Filter”var filter = new QueryFilter{ PartitionKey = "user#123", SortKeyCondition = SortKeyCondition.BeginsWith("order#")};
var options = new QueryOptions{ Limit = 50, ScanForward = false // Descending order};
var result = await client.QueryAsync(filter, options);
if (result.IsSuccess){ foreach (var item in result.Value.Items) { Console.WriteLine($"Order: {item.SortKey}"); }
// Handle pagination if (result.Value.HasMore) { var nextPage = await client.QueryAsync(filter, new QueryOptions { NextToken = result.Value.NextToken }); }}Sort Key Conditions
Section titled “Sort Key Conditions”// Exact matchSortKeyCondition.Equal("profile")
// Prefix matchSortKeyCondition.BeginsWith("order#")
// Range (inclusive)SortKeyCondition.Between("2024-01-01", "2024-12-31")
// ComparisonSortKeyCondition.LessThan("2024-06-01")SortKeyCondition.GreaterThan("2024-01-01")SortKeyCondition.LessThanOrEquals("2024-06-01")SortKeyCondition.GreaterThanOrEquals("2024-01-01")var options = new PaginationOptions{ Limit = 100};
var result = await client.ScanAsync(options);
if (result.IsSuccess){ Console.WriteLine($"Found {result.Value.Items.Count} items");}Batch Operations
Section titled “Batch Operations”Batch Write
Section titled “Batch Write”var writeItems = new List<BatchWriteItem>{ new() { Operation = BatchOperation.Put, PartitionKey = "user#123", SortKey = "profile", Data = new Dictionary<string, object?> { ["name"] = "John" } }, new() { Operation = BatchOperation.Delete, PartitionKey = "user#789", SortKey = "profile" }};
var result = await client.BatchWriteAsync(writeItems);Console.WriteLine($"Success: {result.Value.SuccessCount}");Batch Get
Section titled “Batch Get”var keys = new List<ItemKey>{ new("user#123", "profile"), new("user#456", "profile")};
var result = await client.BatchGetAsync(keys);
foreach (var item in result.Value.Items){ Console.WriteLine($"{item.PartitionKey}: {item.GetAttribute<string>("name")}");}Transactions
Section titled “Transactions”Transactional Write
Section titled “Transactional Write”var writeItems = new List<TransactWriteItem>{ new() { Action = TransactAction.Put, PartitionKey = "account#A", SortKey = "balance", Data = new Dictionary<string, object?> { ["amount"] = 900 } }, new() { Action = TransactAction.Put, PartitionKey = "account#B", SortKey = "balance", Data = new Dictionary<string, object?> { ["amount"] = 1100 } }};
var result = await client.TransactWriteAsync(writeItems, "transfer-12345");
if (result.IsSuccess){ Console.WriteLine("Transaction completed!");}else{ Console.WriteLine("Transaction failed - rolled back");}Transactional Get
Section titled “Transactional Get”var getItems = new List<TransactGetItem>{ new() { PartitionKey = "user#123", SortKey = "profile" }, new() { PartitionKey = "user#123", SortKey = "settings" }};
var result = await client.TransactGetAsync(getItems);
foreach (var item in result.Value.Items){ if (item.ItemExists) { Console.WriteLine($"{item.PartitionKey}: found"); }}Repository Pattern
Section titled “Repository Pattern”For typed entities, use the repository pattern:
// Define your entitypublic record Customer : EntityBase{ public required string Name { get; init; } public required string Email { get; init; } public CustomerTier Tier { get; init; } = CustomerTier.Standard;}
// Get repositoryvar customers = client.GetRepository<Customer>("repo_customers");
// Createvar customer = new Customer{ Id = Guid.NewGuid().ToString(), Name = "Acme Corp", Email = "contact@acme.com"};await customers.CreateAsync(customer);
// Readvar result = await customers.GetAsync(customer.Id);
// Updatevar updated = customer with { Tier = CustomerTier.Premium };await customers.UpdateAsync(updated);
// Deleteawait customers.DeleteAsync(customer.Id);
// Listvar list = await customers.ListAsync(new PaginationOptions { Limit = 50 });
// Check existsvar exists = await customers.ExistsAsync(customer.Id);See Repository Pattern Guide for more details.
Error Handling
Section titled “Error Handling”All operations return Result<T> objects:
var result = await client.GetItemAsync("user#123");
if (result.IsSuccess){ var item = result.Value; // Process item}else if (result.IsFailed){ foreach (var error in result.Errors) { Console.WriteLine($"Error: {error.Message}"); }}Common Patterns
Section titled “Common Patterns”// Throw on failurevar item = result.ValueOrThrow();
// Provide defaultvar item = result.ValueOr(defaultItem);
// Match patternresult.Match( onSuccess: item => Console.WriteLine($"Found: {item.PartitionKey}"), onFailure: errors => Console.WriteLine($"Failed: {errors.First().Message}"));Cleanup
Section titled “Cleanup”Always dispose the client when done:
await client.DisposeAsync();
// Or use 'using' statementawait using var client = new TerraScaleDatabase(options);Next Steps
Section titled “Next Steps”- Repository Pattern - Typed entity storage
- C# Management Client - User and org management
- API Reference - Complete API documentation