The Polypheny .NET driver connects C# applications to Polypheny-DB over the Prism query interface. It supports SQL, MongoQL (MQL), and entity metadata. See the driver reference for version requirements and supported APIs.
Install the driver
Use a .NET 8 SDK for these examples. Start a Polypheny-DB instance with the Prism interface enabled. The examples use localhost:20590 and the default local development credentials pa with an empty password. Set the POLYPHENY_CONNECTION environment variable to override the connection string using the format host:port,user:password.
dotnet new console --framework net8.0 --output PolyphenyExample
cd PolyphenyExample
dotnet add package PolyphenyDotNetDriver --version 2.0.0
Replace Program.cs with either C# example below. Run it from the project directory.
dotnet run
Write and read SQL rows
On a development database, create this table from the SQL console in Polypheny.
CREATE TABLE public.dotnet_example_books (
id INTEGER PRIMARY KEY,
title VARCHAR(80) NOT NULL
);
The example inserts one row using positional parameters and commits the transaction before reading it back. Run it once on the empty table, or change the ID before running it again.
using PolyphenyDotNetDriver;
var connectionString = Environment.GetEnvironmentVariable("POLYPHENY_CONNECTION")
?? "localhost:20590,pa:";
using var connection = PolyphenyDriver.OpenConnection(connectionString);
await connection.OpenAsync();
using var transaction = connection.BeginTransaction();
using var insert = new PolyphenyCommand()
.WithConnection(connection)
.WithTransaction(transaction)
.WithCommandText("INSERT INTO public.dotnet_example_books (id, title) VALUES (?, ?)")
.WithParameterValues(new object[] { 1, "Prism guide" });
insert.Prepare();
insert.ExecuteNonQuery();
transaction.Commit();
using var query = new PolyphenyCommand()
.WithConnection(connection)
.WithCommandText("SELECT id, title FROM public.dotnet_example_books ORDER BY id");
using var reader = query.ExecuteReader();
while (reader.Read())
{
Console.WriteLine($"{reader.GetInt32(0)} {reader.GetString(1)}");
}
Call transaction.Rollback() to discard pending writes. The connection factory constructs the connection, and Open() or OpenAsync() performs the connection and handshake.
Query documents and discover collection metadata
Create a document namespace in the SQL console.
CREATE DOCUMENT NAMESPACE dotnet_example_clinic;
Select dotnet_example_clinic in the MQL console and run these statements in order.
db.createCollection("symptoms");
db.symptoms.insertMany([
{ "patient_id": 41, "complications": { "renal": true } },
{ "patient_id": 42 }
]);
Use a server with Prism 2.2 document metadata support to run the full example. ExecuteQueryMongo() reads document values, and SearchEntitiesAsync() describes the collection without running an MQL query.
using PolyphenyDotNetDriver;
var connectionString = Environment.GetEnvironmentVariable("POLYPHENY_CONNECTION")
?? "localhost:20590,pa:";
using var connection = PolyphenyDriver.OpenConnection(connectionString);
await connection.OpenAsync();
const string namespaceName = "dotnet_example_clinic";
using var query = new PolyphenyCommand()
.WithConnection(connection)
.WithCommandText("db.symptoms.find()");
foreach (var document in query.ExecuteQueryMongo(namespaceName))
{
Console.WriteLine($"Patient {document["patient_id"]}");
if (document.TryGetValue("complications", out var value)
&& value is Dictionary<object, object> complications
&& complications.TryGetValue("renal", out var renal))
{
Console.WriteLine($"Renal complication: {renal}");
}
}
var entities = await connection.SearchEntitiesAsync(namespaceName, "symptoms");
foreach (var entity in entities)
{
if (entity.Document is not { } collection)
continue;
Console.WriteLine($"{collection.NamespaceName}.{collection.CollectionName}");
foreach (var field in collection.Fields)
{
Console.WriteLine($"{field.FieldPath} ({field.TypeName}), optional={field.IsOptional}");
}
if (collection.HasSampleDocumentJson)
Console.WriteLine(collection.SampleDocumentJson);
foreach (var index in collection.DocumentIndexes)
{
Console.WriteLine($"{index.FieldPath} ({index.IndexType}), unique={index.Unique}");
}
}
Omit the entity pattern to list the namespace. The same methods return Entity.Table for SQL tables. Fields can be inferred from a bounded sample, so the returned paths and types may cover only part of a collection. Empty collections can have no sample, and the index list depends on the storage adapter.