Update a row (C#)

Updates a single row in a table.

If the row does not already exist and the update includes at least one non-null or non-empty value, creates a new row.

For general information about working with tables and rows, see About tables with the Data API (C#).

Ready to write code? See the examples for this method to get started. If you are new to the Data API, check out the quickstart.

Result

Updates the specified row.

If no row matches the specified primary key and the update includes at least one non-null or non-empty value, then a new row is created with the specified $set values and primary key values. Any omitted or $unset columns are set to null in the new row.

Does not return anything.

A rare edge case, related to underlying Apache Cassandra® functionality, can cause a row to disappear altogether when all of its columns are set to null.

This happens if the row was previously created from an update operation that had no pre-existing row to modify.

Parameters

Use the UpdateOneAsync method, which belongs to the Table class. You can also use UpdateOne, which is the synchronous version of the method.

Method signature
public Task UpdateOneAsync(
  TableFilter<T> filter,
  UpdateBuilder<T> update,
  TableUpdateOneOptions<T> options = null
);
Name Type Summary

filter

TableFilter

Describes the full primary key of the row to update.

For this method, the filter can only use the $eq operator and columns in the primary key.

update

UpdateBuilder

Defines the update using Data API operators.

For a list of available operators and more examples, see Update operators for tables (C#).

You cannot update primary key values. If you need to modify a row’s primary key, delete the row and then insert a new row with the desired primary key values.

options

TableUpdateOneOptions

Optional. General API options for this operation, including the timeout. For more information and examples, see Customize API interaction.

Examples

The following examples demonstrate how to update a row in a table.

Update multiple columns

You can combine multiple operators and properties in a single call. For the full list of operators, see Update operators for tables (C#).

If the row does not already exist and the update includes at least one non-null or non-empty value, creates a new row.

  • Typed

  • Untyped

You can manually define a client-side type for your table to help statically catch errors. For more information and examples, see Custom typing for tables.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core.Query;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Book
{
  [ColumnPrimaryKey(1)]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnPrimaryKey(2)]
  [ColumnName("author")]
  public string Author { get; set; } = null!;

  [ColumnName("rating")]
  public float? Rating { get; set; }

  [ColumnName("genres")]
  public HashSet<string>? Genres { get; set; }

  [ColumnName("borrower")]
  public string? Borrower { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<Book>("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Book>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq(b => b.Title, "Hidden Shadows of the Past"),
      filterBuilder.Eq(b => b.Author, "John Anthony")
    );

    var update = Builders<Book>
      .TableUpdate.Set(x => x.Rating, 4.5f)
      .Set(x => x.Genres, new HashSet<string> { "Fiction", "Drama" })
      .Unset(x => x.Borrower);

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Row>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq("title", "Hidden Shadows of the Past"),
      filterBuilder.Eq("author", "John Anthony")
    );

    var update = Builders<Row>
      .TableUpdate.Set("rating", 4.5)
      .Set("genres", new HashSet<string> { "Fiction", "Drama" })
      .Unset("borrower");

    await table.UpdateOneAsync(filter, update);
  }
}

Update a map column

The C# client supports updates of a row with a map column that includes non-string keys. (You don’t need to use an array of key-value pairs to represent the map column.)

  • Typed

  • Untyped

You can manually define a client-side type for your collection to help statically catch errors. For more information and examples, see Custom typing for collections.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Book
{
  [ColumnPrimaryKey(1)]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnPrimaryKey(2)]
  [ColumnName("author")]
  public string Author { get; set; } = null!;

  [ColumnName("map_column_int_str")]
  public Dictionary<int, string>? MapColumnIntStr { get; set; }

  [ColumnName("map_column_str_str")]
  public Dictionary<string, string>? MapColumnStrStr { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<Book>("TABLE_NAME");

    var mapColumnIntStr = new Dictionary<int, string>
    {
      { 1, "value1" },
      { 2, "value2" },
    };

    var mapColumnStrStr = new Dictionary<string, string>
    {
      { "key1", "value1" },
      { "key2", "value2" },
    };

    var filterBuilder = Builders<Book>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq(b => b.Title, "Hidden Shadows of the Past"),
      filterBuilder.Eq(b => b.Author, "John Anthony")
    );

    var update = Builders<Book>
      .TableUpdate.Set(b => b.MapColumnIntStr, mapColumnIntStr)
      .Set(b => b.MapColumnStrStr, mapColumnStrStr);

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    var mapColumnIntStr = new Dictionary<int, string>
    {
      { 1, "value1" },
      { 2, "value2" },
    };

    var mapColumnStrStr = new Dictionary<string, string>
    {
      { "key1", "value1" },
      { "key2", "value2" },
    };

    var filterBuilder = Builders<Row>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq("title", "Hidden Shadows of the Past"),
      filterBuilder.Eq("author", "John Anthony")
    );

    var update = Builders<Row>
      .TableUpdate.Set("map_column_int_str", mapColumnIntStr)
      .Set("map_column_str_str", mapColumnStrStr);

    await table.UpdateOneAsync(filter, update);
  }
}

Append to a list or set column

Use $push to append a single element to a list or set. Use $push with $each to append multiple elements.

  • Typed

  • Untyped

You can manually define a client-side type for your collection to help statically catch errors. For more information and examples, see Custom typing for collections.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core.Query;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Book
{
  [ColumnPrimaryKey(1)]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnPrimaryKey(2)]
  [ColumnName("author")]
  public string Author { get; set; } = null!;

  [ColumnName("genres")]
  public HashSet<string>? Genres { get; set; }

  [ColumnName("topics")]
  public HashSet<string>? Topics { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<Book>("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Book>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq(b => b.Title, "Hidden Shadows of the Past"),
      filterBuilder.Eq(b => b.Author, "John Anthony")
    );

    var update = Builders<Book>
      .TableUpdate.Push(x => x.Genres, "SciFi")
      .PushEach(x => x.Topics, ["robots", "AI"]);

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    var filterBuilder = Builders<Row>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq("title", "Hidden Shadows of the Past"),
      filterBuilder.Eq("author", "John Anthony")
    );

    var update = Builders<Row>
      .TableUpdate.Push("genres", "SciFi")
      .PushEach("topics", ["robots", "AI"]);

    await table.UpdateOneAsync(filter, update);
  }
}

Append to a map column

Use $push to append a single key-value pair to a map. Use $push with $each to append multiple key-value pairs.

  • Typed

  • Untyped

You can manually define a client-side type for your collection to help statically catch errors. For more information and examples, see Custom typing for collections.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Book
{
  [ColumnPrimaryKey(1)]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnPrimaryKey(2)]
  [ColumnName("author")]
  public string Author { get; set; } = null!;

  [ColumnName("map_column_int_str")]
  public Dictionary<int, string>? MapColumnIntStr { get; set; }

  [ColumnName("map_column_str_str")]
  public Dictionary<string, string>? MapColumnStrStr { get; set; }

  [ColumnName("map_column_int_str_2")]
  public Dictionary<int, string>? MapColumnIntStr2 { get; set; }

  [ColumnName("map_column_str_str_2")]
  public Dictionary<string, string>? MapColumnStrStr2 { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<Book>("TABLE_NAME");

    var filterBuilder = Builders<Book>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq(b => b.Title, "Hidden Shadows of the Past"),
      filterBuilder.Eq(b => b.Author, "John Anthony")
    );

    var update = Builders<Book>
      .TableUpdate.Push(
        b => b.MapColumnIntStr,
        new Dictionary<int, string> { { 1, "value1" } }
      )
      .Push(
        b => b.MapColumnStrStr,
        new Dictionary<string, string> { { "key1", "value1" } }
      )
      .PushEach(
        b => b.MapColumnIntStr2,
        new Dictionary<int, string> { { 1, "value1" }, { 2, "value2" } }
      )
      .PushEach(
        b => b.MapColumnStrStr2,
        new Dictionary<string, string>
        {
          { "key1", "value1" },
          { "key2", "value2" },
        }
      );

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    var filterBuilder = Builders<Row>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq("title", "Hidden Shadows of the Past"),
      filterBuilder.Eq("author", "John Anthony")
    );

    var update = Builders<Row>
      .TableUpdate.Push(
        "map_column_int_str",
        new Dictionary<int, string> { { 1, "value1" } }
      )
      .Push(
        "map_column_str_str",
        new Dictionary<string, string> { { "key1", "value1" } }
      )
      .PushEach(
        "map_column_int_str_2",
        new Dictionary<int, string> { { 1, "value1" }, { 2, "value2" } }
      )
      .PushEach(
        "map_column_str_str_2",
        new Dictionary<string, string>
        {
          { "key1", "value1" },
          { "key2", "value2" },
        }
      );
    await table.UpdateOneAsync(filter, update);
  }
}

Remove matches from a list or set column

Use $pullAll to remove the specified elements from a list or set.

  • Typed

  • Untyped

You can manually define a client-side type for your collection to help statically catch errors. For more information and examples, see Custom typing for collections.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core.Query;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Book
{
  [ColumnPrimaryKey(1)]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnPrimaryKey(2)]
  [ColumnName("author")]
  public string Author { get; set; } = null!;

  [ColumnName("genres")]
  public HashSet<string>? Genres { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<Book>("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Book>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq(b => b.Title, "Hidden Shadows of the Past"),
      filterBuilder.Eq(b => b.Author, "John Anthony")
    );

    var update = Builders<Book>.TableUpdate.PullAll(
      x => x.Genres,
      new[] { "SciFi", "Romance" }
    );

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Row>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq("title", "Hidden Shadows of the Past"),
      filterBuilder.Eq("author", "John Anthony")
    );

    var update = Builders<Row>.TableUpdate.PullAll(
      "genres",
      new[] { "SciFi", "Romance" }
    );

    await table.UpdateOneAsync(filter, update);
  }
}

Remove matches from map column

Use $pullAll to remove entries that match the specified keys from a map column.

  • Typed

  • Untyped

You can manually define a client-side type for your collection to help statically catch errors. For more information and examples, see Custom typing for collections.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core.Query;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Book
{
  [ColumnPrimaryKey(1)]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnPrimaryKey(2)]
  [ColumnName("author")]
  public string Author { get; set; } = null!;

  [ColumnName("metadata")]
  public Dictionary<string, string>? Metadata { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<Book>("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Book>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq(b => b.Title, "Hidden Shadows of the Past"),
      filterBuilder.Eq(b => b.Author, "John Anthony")
    );

    var update = Builders<Book>.TableUpdate.PullAll(
      x => x.Metadata,
      new[] { "language", "edition" }
    );

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Row>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq("title", "Hidden Shadows of the Past"),
      filterBuilder.Eq("author", "John Anthony")
    );

    var update = Builders<Row>.TableUpdate.PullAll(
      "metadata",
      new[] { "language", "edition" }
    );

    await table.UpdateOneAsync(filter, update);
  }
}

Unset columns

To unset a column, you can use the $unset operator, or you can use the $set operator and an empty value. Either operation will delete the value in the specified column.

Unsetting a column produces a tombstone. Excessive tombstones can impact query performance.

  • Typed

  • Untyped

You can manually define a client-side type for your table to help statically catch errors. For more information and examples, see Custom typing for tables.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core.Query;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Book
{
  [ColumnPrimaryKey(1)]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnPrimaryKey(2)]
  [ColumnName("author")]
  public string Author { get; set; } = null!;

  [ColumnName("number_of_pages")]
  public int? NumberOfPages { get; set; }

  [ColumnName("genres")]
  public HashSet<string>? Genres { get; set; }

  [ColumnName("due_date")]
  public DateOnly? DueDate { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<Book>("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Book>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq(b => b.Title, "Hidden Shadows of the Past"),
      filterBuilder.Eq(b => b.Author, "John Anthony")
    );

    var update = Builders<Book>.TableUpdate.Unset(x => x.Genres);

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    // Update a row
    var filterBuilder = Builders<Row>.TableFilter;
    var filter = filterBuilder.And(
      filterBuilder.Eq("title", "Hidden Shadows of the Past"),
      filterBuilder.Eq("author", "John Anthony")
    );

    var update = Builders<Row>.TableUpdate.Unset("genres");

    await table.UpdateOneAsync(filter, update);
  }
}

Update a user-defined type column

If a column is a user-defined type, you must update the whole value. You can’t update a partial value. In the example below, president and vice_president both use the same user-defined type, which consists of an email and user_name field.

If the value type of a map, list, or set column is a user-defined type, you can only update the whole value, not a partial value, for each entry. The $push, $each, and $pullAll operators work on map, list, and set columns that have a user-defined type as their value type. For examples, see Update a map column, Append to a list or set column, Append to a map column, Remove matches from a list or set column, and Remove matches from map column.

  • Typed

  • Untyped

You can manually define a client-side type for your table to help statically catch errors. For more information and examples, see Custom typing for tables.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

[UserDefinedType("example_udt")]
public class ExampleUDT
{
  [ColumnName("email")]
  public string? Email { get; set; }

  [ColumnName("user_name")]
  public string? UserName { get; set; }
};

public class ExampleRow
{
  [ColumnPrimaryKey]
  [ColumnName("title")]
  public string Title { get; set; } = null!;

  [ColumnName("president")]
  public ExampleUDT? President { get; set; }

  [ColumnName("vice_president")]
  public ExampleUDT? VicePresident { get; set; }
}

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable<ExampleRow>("TABLE_NAME");
    ;

    // Update a row
    var filter = Builders<ExampleRow>.TableFilter.Eq(
      x => x.Title,
      "Chemistry Club"
    );

    var update = Builders<ExampleRow>
      .TableUpdate.Set(
        x => x.President,
        new ExampleUDT { Email = "lisa@example.com", UserName = "lisa_m" }
      )
      .Set(
        x => x.VicePresident,
        new ExampleUDT
        {
          Email = "tanya@example.com",
          UserName = "tanya_o",
        }
      );

    await table.UpdateOneAsync(filter, update);
  }
}

If you don’t pass a type parameter, the collection or table remains untyped. This is a more flexible but less type-safe option.

using DataStax.AstraDB.DataApi;
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Tables;

namespace Examples;

public class Program
{
  static async Task Main()
  {
    // Get an existing table
    var client = new DataAPIClient(
      new CommandOptions() { Destination = DataAPIDestination.HCD }
    );

    var database = client.GetDatabase(
      "API_ENDPOINT",
      DataAPIClient.UsernamePasswordTokenProvider(
        "USERNAME",
        "PASSWORD"
      ),
      "KEYSPACE_NAME"
    );

    var table = database.GetTable("TABLE_NAME");

    // Update a row
    var filter = Builders<Row>.TableFilter.Eq("title", "Chemistry Club");

    var update = Builders<Row>
      .TableUpdate.Set(
        "president",
        new Dictionary<string, string>
        {
          ["email"] = "lisa@example.com",
          ["user_name"] = "lisa_m",
        }
      )
      .Set(
        "vice_president",
        new Dictionary<string, string>
        {
          ["email"] = "tanya@example.com",
          ["user_name"] = "tanya_o",
        }
      );

    await table.UpdateOneAsync(filter, update);
  }
}

Client reference

For more information, see the client reference.

Was this helpful?

Give Feedback

How can we improve the documentation?

© Copyright IBM Corporation 2026 | Privacy policy | Terms of use Manage Privacy Choices

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries. Kubernetes is the registered trademark of the Linux Foundation.

General Inquiries: Contact IBM