Skip to main content
Version: 1.0.2

.NET

.NET SDK for SurrealDB

The SurrealDB SDK for .NET enables simple and advanced querying of a remote database from client or server-side code. Remote connections automatically reconnect when the connection is terminated.

To contribute to this documentation, edit this file on GitHub.

To contribute to the SDK code, submit an Issue or Pull Request here.


Install the SDK

Create a new project using your favorite IDE (Visual Studio, JetBrains Rider, etc...)

or use the dotnet new command.

Once ready, add the SurrealDB SDK to your dependencies:

dotnet add package SurrealDb.Net

Connect to SurrealDB

Let's start by creating a new console app.

dotnet new console -o SurrealDbExample
cd SurrealDbExample
dotnet add package SurrealDb.Net

Open Program.cs and replace everything in there with the following code to try out some basic operations using the SurrealDB SDK.

using SurrealDb.Net;
using SurrealDb.Net.Models;
using SurrealDb.Net.Models.Auth;
using System.Text.Json;

var db = new SurrealDbClient("ws://127.0.0.1:8000/rpc");

await db.SignIn(new RootAuth { Username = "root", Password = "root" });
await db.Use("test", "test");

var person = new Person
{
Title = "Founder & CEO",
Name = new() { FirstName = "Tobie", LastName = "Morgan Hitchcock" },
Marketing = true
};
var created = await db.Create("person", person);
Console.WriteLine(ToJsonString(created));

var updated = await db.Merge<ResponsibilityMerge, Person>(
new() { Id = new Thing("person", "jaime"), Marketing = true }
);
Console.WriteLine(ToJsonString(updated));

var people = await db.Select<Person>("person");
Console.WriteLine(ToJsonString(people));

var queryResponse = await db.Query(
"SELECT marketing, count() FROM type::table($table) GROUP BY marketing",
new Dictionary<string, object> { { "table", "person" } }
);
var groups = queryResponse.GetValue<List<Group>>(0);
Console.WriteLine(ToJsonString(groups));

static string ToJsonString(object? o)
{
return JsonSerializer.Serialize(o, new JsonSerializerOptions
{
WriteIndented = true,
});
}

public class Person : Record
{
public string? Title { get; set; }
public Name? Name { get; set; }
public bool Marketing { get; set; }
}
public class Name
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
}
public class ResponsibilityMerge : Record
{
public bool Marketing { get; set; }
}
public class Group
{
public bool Marketing { get; set; }
public int Count { get; set; }
}

Then make sure your SurrealDB server is running on 127.0.0.1:8000 and run your app from the command line with:

dotnet run

SDK methods

The .NET SDK comes with a number of built-in functions.

FunctionDescription
new SurrealDbClient(endpoint)Creates a new client, detecting the right protocol from the endpoint
SurrealDbHttpClient.New(host)StaticInitialises a client using HTTP protocol
SurrealDbHttpsClient.New(host)StaticInitialises a client using HTTPS protocol
SurrealDbWsClient.New(host)StaticInitialises a client using WS protocol
SurrealDbWssClient.New(host)StaticInitialises a client using WSS protocol
db.Configure(ns,db,credentials) Configures the client to use a specific namespace and database, with credentials
await db.Connect(url, options) Connects the client to the underlying endpoint, also improving performance to avoid cold starts
await db.Use(ns,db)Switch to a specific namespace and database
await db.Signup(credentials)Signs up a user to a specific authentication scope
await db.Signin(credentials)Signs this connection in to a specific authentication scope
await db.Authenticate(token)Authenticates the current connection with a JWT token
await db.Invalidate()Invalidates the authentication for the current connection
await db.Set(key,val)Assigns a value as a parameter for this connection
await db.Unset(key)Removes a parameter for this connection
await db.Query(sql,params)Runs a set of SurrealQL statements against the database
await db.Select(resource)Selects all records in a table, or a specific record
await db.Create(resource,data)Creates a record in the database
await db.Upsert(data)Creates or updates a specific record
await db.Merge(resource,data)Modifies all records in a table, or a specific record
await db.Delete(resource,data)Deletes all records, or a specific record
await db.Version()Retrieves the version of the SurrealDB instance
await db.Health()Checks the status of the database server and storage engine

SurrealDbClient

Creates a new client, detecting the right protocol from the endpoint.

Method Syntax
new SurrealDbClient(endpoint)

Arguments

ArgumentsDescription
endpointREQUIREDThe database endpoint to connect to.
httpClientFactoryOPTIONALAn IHttpClientFactory instance.

Example usage

// Creates a new client using a local endpoint
var db = new SurrealDbClient("http://127.0.0.1:8000");

// Creates a new client using a remote endpoint
var db = new SurrealDbClient("wss://cloud.surrealdb.com");

SurrealDbHttpClient

Initialises a client using HTTP protocol.

Method Syntax
SurrealDbHttpClient.new(host)

Arguments

ArgumentsDescription
hostREQUIREDThe database host to connect to.
httpClientFactoryOPTIONALAn IHttpClientFactory instance.

Example usage

var db = SurrealDbHttpClient.New("127.0.0.1:8000");

SurrealDbHttpsClient

Initialises a client using HTTPS protocol.

Method Syntax
SurrealDbHttpsClient.new(host)

Arguments

ArgumentsDescription
hostREQUIREDThe database host to connect to.
httpClientFactoryOPTIONALAn IHttpClientFactory instance.

Example usage

var db = SurrealDbHttpClient.New("cloud.surrealdb.com");

SurrealDbWsClient

Initialises a client using WS protocol.

Method Syntax
SurrealDbWsClient.New(host)

Arguments

ArgumentsDescription
hostREQUIREDThe database host to connect to.
nsOPTIONALThe table namespace to connect to.
dbOPTIONALThe table database to connect to.
usernameOPTIONALThe username to connect to (with root access).
passwordOPTIONALThe password to connect to (with root access).

Example usage

var db = SurrealDbWsClient.New("127.0.0.1:8000");

SurrealDbWssClient

Initialises a client using WSS protocol.

Method Syntax
SurrealDbWssClient.New(host)

Arguments

ArgumentsDescription
hostREQUIREDThe database host to connect to.
nsOPTIONALThe table namespace to connect to.
dbOPTIONALThe table database to connect to.
usernameOPTIONALThe username to connect to (with root access).
passwordOPTIONALThe password to connect to (with root access).

Example usage

var db = SurrealDbWssClient.New("cloud.surrealdb.com");

.Configure()

Configures the client to use a specific namespace and database, with credentials.

Method Syntax
db.Configure(ns, db, credentials)

Arguments

ArgumentsDescription
nsOPTIONALThe table namespace to use.
dbOPTIONALThe table database to use.
usernameOPTIONALThe username with root access.
passwordOPTIONALThe password with root access.
tokenOPTIONALThe value of the JWT token.

Example usage

// Configure a connection to use ns/db
client.Configure("ns", "db");

// Configure a connection to use ns/db, as well as root access (with username and password)
client.Configure("ns", "db", "root", "root");

// Configure a connection to use ns/db, as well as user auth via JWT token
string token = "eyJhbGciOiJIUzI1...";
client.Configure("ns", "db", token);

.Connect()

Connects the client to the underlying endpoint, also improving performance to avoid cold starts.

Method Syntax
await db.Connect()

Arguments

ArgumentsDescription
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await db.Connect();

.Use()

Switch to a specific namespace and database.

Method Syntax
await db.Use(ns, db)

Arguments

ArgumentsDescription
nsINITIALLY REQUIREDSwitches to a specific namespace.
dbINITIALLY REQUIREDSwitches to a specific database.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await db.Use("test", "test");

.SignUp()

Signs up to a specific authentication scope.

Method Syntax
await db.SignUp(credentials)

Arguments

ArgumentsDescription
credentialsREQUIREDCredentials to sign up as a scoped user.
cancellationTokenREQUIREDThe cancellationToken enables graceful cancellation of asynchronous operations.
var authParams = new AuthParams
{
Namespace = "test",
Database = "test",
Scope = "user",
Email = "info@surrealdb.com",
Password = "123456"
};

Jwt jwt = await db.SignUp(authParams);

public class AuthParams : ScopeAuth
{
public string? Username { get; set; }
public string? Email { get; set; }
public string? Password { get; set; }
}

.SignIn()

Signs in to a specific authentication scope.

Method Syntax
await db.SignIn(credentials)

Arguments

ArgumentsDescription
credentialsREQUIREDVariables used in a signin query.
cancellationTokenREQUIREDThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Option 1: Sign in as root user
await db.SignIn(new RootAuth { Username = "root", Password = "root" });

// Option 2: Sign in using namespace auth
await db.SignIn(
new NamespaceAuth
{
Namespace = "test",
Username = "johndoe",
Password = "password123"
}
);

// Option 3: Sign in using database auth
await db.SignIn(
new DatabaseAuth
{
Namespace = "test",
Database = "test",
Username = "johndoe",
Password = "password123"
}
);

// Option 4: Sign in as a scoped used
var authParams = new AuthParams
{
Namespace = "test",
Database = "test",
Scope = "user",
Email = "info@surrealdb.com",
Password = "123456"
};

Jwt jwt = await db.SignIn(authParams);

public class AuthParams : ScopeAuth
{
public string? Username { get; set; }
public string? Email { get; set; }
public string? Password { get; set; }
}

.Authenticate()

Authenticates the current connection with a JWT token.

Method Syntax
await db.Authenticate(jwt)

Arguments

ArgumentsDescription
jwtREQUIREDThe JWT object holder of the authentication token.
cancellationTokenREQUIREDThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Sign in or sign up as a scoped user
Jwt jwt = await db.SignUp(authParams);

await db.Authenticate(jwt);

.Invalidate()

Invalidates the authentication for the current connection.

Method Syntax
await db.Invalidate()

Arguments

PropertiesDescription
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

db.Invalidate();

.Set()

Assigns a value as a parameter for this connection.

Method Syntax
await db.Set(key, val)

Arguments

ArgumentsDescription
keyREQUIREDSpecifies the name of the variable.
valueREQUIREDAssigns the value to the variable name.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Assign the variable on the connection
await db.Set("name", new Name { FirstName = "Tobie", LastName = "Morgan Hitchcock" });

// Use the variable in a subsequent query
await db.Query("CREATE person SET name = $name");

// Use the variable in a subsequent query
await db.Query("SELECT * FROM person WHERE name.first_name = $name.first_name");

.Unset()

Removes a parameter for this connection.

Method Syntax
await db.Unset(key)

Arguments

ArgumentsDescription
keyREQUIREDSpecifies the SurrealQL statements.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await db.Unset("name");

.Query()

Runs a set of SurrealQL statements against the database.

Method Syntax
await db.Query(sql, params)

Arguments

ArgumentsDescription
sqlREQUIREDSpecifies the SurrealQL statements.
paramsOPTIONALAssigns variables which can be used in the query.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Assign the variable on the connection
var params = new Dictionary<string, object> { { "table", "person" } };
var result = await db.Query("CREATE person; SELECT * FROM type::table($table);", params);

// Get the first result from the first query
var created = result.GetValue<Person>(0);

// Get all of the results from the second query
var people = result.GetValue<List<Person>>(1);

.Select()

Selects all records in a table, or a specific record, from the database.

Method Syntax
await db.Select(resource)

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or a record ID to select.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Select all records from a table
var people = await db.Select<Person>("person");

// Select a specific record from a table
var person = await db.Select<Person>("person", "h5wxrf2ewk8xjxosxtyc");

// Select a specific record from a table, equivalent to the above
var thing = new Thing("person", "h5wxrf2ewk8xjxosxtyc");
var person = await db.Select<Person>(thing);

// Select a specific record from a table, given a non-string id
var thing = Thing.From("person", new Guid("8424486b-85b3-4448-ac8d-5d51083391c7"));
var person = await db.Select<Person>(thing);

.Create()

Creates a record in the database.

Method Syntax
await db.Create(resource, data)

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or the specific record ID to create.
dataOPTIONALThe document / record data to insert.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Create a record with a random ID
var person = await db.Create<Person>("person");

// Create a record with a random ID & specific fields
var person = await db.Create("person", new Person { Name = "Tobie" });

// Create a record with a specific ID
var personToCreate = new Person
{
Id = new Thing("person", "tobie"),
Name = "Tobie",
Settings = new Settings
{
Active = true,
Marketing = true,
},
};
var result = await db.Create(personToCreate);

.Upsert()

Creates or updates a specific record.

Method Syntax
await db.Upsert(data)
NOTE: This function creates a new document / record or replaces the current one with the specified data.

Arguments

ArgumentsDescription
dataREQUIREDThe document / record data to insert.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

var person = new Person
{
Id = new Thing("person", "tobie"), // Id is mandatory to apply create or update
Name = "Tobie",
Settings = new Settings
{
Active = true,
Marketing = true,
},
};

// Create a new record when it doesn't exist
var created = await db.Upsert(person);

// Update an existing record when it does exist
var updated = await db.Upsert(person);

.Merge()

Modifies all records in a table, or a specific record.

Method Syntax
await db.Merge(resource, data)

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or the specific record ID to modify.
dataOPTIONALThe data with which to modify the records.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Only changes the fields specified in the merge object
var merge = new PersonMerge
{
Id = new Thing("person", "tobie"),
Settings = new Settings
{
Active = true,
Marketing = false,
},
};
var result = await db.Merge<PersonMerge, Person>(merge);

// Only changes the fields specified in the Dictionary
var thing = new Thing("person", "tobie");
var data = new Dictionary<string, object>
{
{ "tags", new List<string> { "developer", "engineer" } }
};

var result = await db.Merge<Person>(thing, data);

.Delete()

Deletes all records in a table, or a specific record, from the database.

Method Syntax
await db.Delete(resource)

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or a record ID to select.
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

// Delete all records from a table
await db.Delete("person");

// Delete a specific record from a table
await db.Delete("person", "h5wxrf2ewk8xjxosxtyc");

// Delete a specific record from a table, equivalent to the above
var thing = new Thing("person", "h5wxrf2ewk8xjxosxtyc");
await db.Delete(thing);

.Version()

Retrieves the version of the SurrealDB instance.

Method Syntax
await db.Version()

Arguments

ArgumentsDescription
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

string version = await db.Version(); // Will return "surrealdb-1.0.0-beta.9+20230402.5eafebd"

.Health()

Checks the status of the database server and storage engine.

Method Syntax
await db.Health()

Arguments

ArgumentsDescription
cancellationTokenOPTIONALThe cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

bool status = await db.Health();


Dependency Injection

The .NET SDK also support Dependency Injection to ease the use of the SurrealDbClient in your application.

Let's start by creating a new ASP.NET Core web app.

dotnet new webapp -o SurrealDbWeatherApi
cd SurrealDbWeatherApi
dotnet add package SurrealDb.Net

Open appsettings.Development.json and replace everything in there with the following code. We have added a new Connection String called SurrealDB with the default configuration.

{
"AllowedHosts": "*",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"SurrealDB": "Server=http://127.0.0.1:8000;Namespace=test;Database=test;Username=root;Password=root"
}
}

Open Program.cs and replace everything in there with the following code. This code is using the AddSurreal() extension method to inject services automatically. Notice that all we have to do is one line of code to configure the SurrealDB client with the previously set Connection String.

NOTE: By default, this function will register both ISurrealDbClient and SurrealDbClient using the Singleton service lifetime.
var builder = WebApplication.CreateBuilder(args);

var services = builder.Services;
var configuration = builder.Configuration;

services.AddControllers();
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
services.AddSurreal(configuration.GetConnectionString("SurrealDB"));

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();

app.MapControllers();

app.Run();

Open WeatherForecastController.cs and replace everything in there with the following code. Finally, we can inject the ISurrealDbClient inside our Controller.

using Microsoft.AspNetCore.Mvc;

namespace SurrealDbWeatherApi.Controllers;

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private const string Table = "weatherForecast";

private readonly ISurrealDbClient _surrealDbClient;

public WeatherForecastController(ISurrealDbClient surrealDbClient)
{
_surrealDbClient = surrealDbClient;
}

[HttpGet]
[Route("/")]
public Task<List<WeatherForecast>> GetAll(CancellationToken cancellationToken)
{
return _surrealDbClient.Select<WeatherForecast>(Table, cancellationToken);
}

[HttpPost]
[Route("/")]
public Task<WeatherForecast> Create(CreateWeatherForecast data, CancellationToken cancellationToken)
{
var weatherForecast = new WeatherForecast
{
Date = data.Date,
Country = data.Country,
TemperatureC = data.TemperatureC,
Summary = data.Summary
};

return _surrealDbClient.Create(Table, weatherForecast, cancellationToken);
}

// ...
// Other methods omitted for brevity
}

public class CreateWeatherForecast
{
public DateTime Date { get; set; }
public string? Country { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
}

Then make sure your SurrealDB server is running on 127.0.0.1:8000 and run your app from the command line with:

dotnet run

Connection Strings

Connection Strings are an easy way to configure your application to connect to a SurrealDB instance. They are stored in the appsettings.json file and can be used to configure the SurrealDbClient.

In general, it is known as a best practice to: set a development Connection String in appsettings.Development.json, store your production Connection String in a Secret environment variable, or even better in a Vault.

KeysDescriptionAliases
EndpointREQUIREDThe database endpoint to connect to.Server
NamespaceOPTIONALSwitches to a specific namespace.NS
DatabaseOPTIONALSwitches to a specific database.DB
UsernameOPTIONALUsername used to have root access.User
PasswordOPTIONALPassword used to have root access.Pass
TokenOPTIONALToken (JWT) used to have user access.

Here is a couple of examples of Connection Strings:

Server=http://127.0.0.1:8000;Namespace=test;Database=test;Username=root;Password=root
Endpoint=http://127.0.0.1:8000;NS=test;DB=test;User=root;Pass=root