---
type: Development Guide
title: Getting Started with Tables as C# Classes in the ScalarDB Cluster .NET Client SDK
description: The ScalarDB Cluster .NET Client SDK helps you write code to access a cluster by abstracting ScalarDB tables as C# objects. After defining a class that represents a table in the cluster, you can ensure that a column name or its type won't...
resource: https://scalardb.scalar-labs.com/docs/3.18/scalardb-cluster-dotnet-client-sdk/getting-started-with-scalardb-tables-as-csharp-classes/
tags:
- scalardb
- v3.18
- phase:implement
- section:develop
- edition:enterprise-standard
- edition:enterprise-premium
status: stable
product: scalardb
product_title: ScalarDB
version: '3.18'
patch_version: 3.18.1
doc_id: scalardb-cluster-dotnet-client-sdk/getting-started-with-scalardb-tables-as-csharp-classes
lifecycle_phase: implement
breadcrumb:
- Develop
- Run Transactions
- Reference
- .NET Interface Guides
editions:
- Enterprise Standard
- Enterprise Premium
generated:
  by: process:okf-build/1.0.0
  at: '2026-08-04T23:50:49Z'
sources:
- id: docs-scalardb
  resource: https://github.com/scalar-labs/docs-scalardb/blob/6126dfe2f56389351d88b134752618641f9771dd/versioned_docs/version-3.18/scalardb-cluster-dotnet-client-sdk/getting-started-with-scalardb-tables-as-csharp-classes.mdx
  title: ScalarDB documentation source (MDX)
  author: process:scalar-labs/docs-scalardb
  last_modified: '2026-08-04T15:05:02Z'
---

# Getting Started with Tables as C# Classes in the ScalarDB Cluster .NET Client SDK

The ScalarDB Cluster .NET Client SDK helps you write code to access a cluster by abstracting ScalarDB tables as C# objects. After defining a class that represents a table in the cluster, you can ensure that a column name or its type won't be mixed up when querying the cluster. In addition, if a table's structure changes, you can apply the changes to the code by using the refactoring feature in your IDE.

:::note

Although we recommend using asynchronous methods, as in the following examples, you can use synchronous methods instead.

:::

## Install the SDK

Install the same major and minor version of the [SDK](https://www.nuget.org/packages/ScalarDB.Client) as ScalarDB Cluster into the .NET project. You can do this by using the built-in NuGet package manager, replacing `<MAJOR>.<MINOR>` with the version that you're using:

```console
dotnet add package ScalarDB.Client --version '<MAJOR>.<MINOR>.*'
```

## Create classes for all ScalarDB tables

To work with ScalarDB tables as C# objects, you must create a class for each table that you want to use. For example:

```c#
using System.ComponentModel.DataAnnotations.Schema;
using ScalarDB.Client.DataAnnotations;

// ...

[Table("ns.statements")]
public class Statement
{
    [PartitionKey]
    [Column("order_id", Order = 0)]
    public string OrderId { get; set; } = String.Empty;

    [ClusteringKey]
    [Column("item_id", Order = 1)]
    public int ItemId { get; set; }

    [Column("count", Order = 2)]
    public int Count { get; set; }
}
```

For details about which types should be used for properties, see [How ScalarDB Column Types Are Converted to and from .NET Types](./common-reference.md#how-scalardb-column-types-are-converted-to-and-from-net-types).

## Execute CRUD operations

After creating a class for each table, you can use the classes as objects by using the generic `GetAsync`, `ScanAsync`, `InsertAsync`, `UpdateAsync`, `DeleteAsync`, `UpsertAsync`, or `MutateAsync` method of `ITransactionCrudOperable`.

To use these generic methods, add the following namespace to the `using` section:

```c#
using ScalarDB.Client.Extensions;
```

### Get one object by using the `GetAsync` method

```c#
var keys = new Dictionary<string, object>
           {
               { nameof(Statement.OrderId), "1" }
           };
var statement = await transaction.GetAsync<Statement>(keys);

Console.WriteLine($"ItemId: {statement.ItemId}, Count: {statement.Count}");
```

### Get multiple objects by using the `ScanAsync` method

```c#
var startKeys = new Dictionary<string, object>
                {
                    { nameof(Statement.OrderId), "1" },
                    { nameof(Statement.ItemId), 3 }
                };
var endKeys = new Dictionary<string, object>
              {
                  { nameof(Statement.ItemId), 6}
              };

await foreach (var s in transaction.ScanAsync<Statement>(startKeys, endKeys))
    Console.WriteLine($"ItemId: {s.ItemId}, Count: {s.Count}");
```

:::note

To use LINQ methods with `IAsyncEnumerable<T>`, you can install [System.Linq.Async](https://www.nuget.org/packages/System.Linq.Async/) package.

:::

### Insert a new object by using the `InsertAsync` method

```c#
var statement = new Statement
                {
                    OrderId = "2",
                    ItemId = 4,
                    Count = 8
                };
await transaction.InsertAsync(statement);
```

### Update an object by using the `UpdateAsync` method

```c#
// ...
statement.ItemId = 4;
statement.Count = 8;

await transaction.UpdateAsync(statement);
```

### Delete an object by using the `DeleteAsync` method

```c#
// ...
await transaction.DeleteAsync(statement);
```

### Upsert an object by using the `UpsertAsync` method

```c#
var statement = new Statement
                {
                    OrderId = "2",
                    ItemId = 4,
                    Count = 8
                };
await transaction.UpsertAsync(statement);
```

### Upsert and delete multiple objects at once by using the `MutateAsync` method

```c#
var statement = new Statement
                {
                    OrderId = "2",
                    ItemId = 4,
                    Count = 16
                };

// ...

await transaction.MutateAsync(objectsToUpsert: new[] { statement },
                              objectsToDelete: new[] { statement2 });
```

:::note

To modify objects by using the `UpdateAsync`, `DeleteAsync`, `UpsertAsync`, or `MutateAsync` method, the objects must be retrieved first by using the `GetAsync` or `ScanAsync` method.

:::

## Use the Administrative API

C# objects also can be used with the Administrative API. To use generic Administrative API methods, add the following namespace to the `using` section:

```c#
using ScalarDB.Client.Extensions;
```

### Create a new namespace

```c#
await admin.CreateNamespaceAsync<Statement>();
```

### Drop an existing namespace

```c#
await admin.DropNamespaceAsync<Statement>();
```

### Check if a namespace exists

```c#
var namespaceExists = await admin.IsNamespacePresentAsync<Statement>();
```

### Create a new table

```c#
await admin.CreateTableAsync<Statement>();
```

### Drop an existing table

```c#
await admin.DropTableAsync<Statement>();
```

### Check if a table exists

```c#
var tableExists = await admin.IsTablePresentAsync<Statement>();
```
