Build applications with Neo4j and .NET
The Neo4j .NET driver is the official library to interact with a Neo4j instance through a .NET application.
At the hearth of Neo4j lies Cypher, the query language to interact with a Neo4j database. Although this guide does not require you to be a seasoned Cypher querier, it’s easier to focus on the .NET-specific bits if you know some Cypher already. You will also get a gentle introduction to Cypher in these pages, but check out Getting started → Cypher for a more detailed walkthrough of graph databases modelling and querying if this is your first approach.
Install
Add the Neo4j .NET driver to your project:
dotnet add package Neo4j.Driver --version {dotnet-driver-version-minor}
The driver supports the .NET Standard 2.0.
Connect to the database
Connect to a database by creating an IDriver
object and providing a URL and an authentication token.
Once you have a IDriver
instance, use the .VerifyConnectivityAsync()
method to ensure that a working connection can be established.
using Neo4j.Driver;
// URI examples: "neo4j://localhost", "neo4j+s://xxx.databases.neo4j.io"
const string dbUri = "<database-uri>";
const string dbUser = "<username>";
const string dbPassword = "<password>";
await using var driver = GraphDatabase.Driver(dbUri, AuthTokens.Basic(dbUser, dbPassword));
await driver.VerifyConnectivityAsync();
Console.WriteLine("Connection established.");
Create an example graph
Run a Cypher query with the method IDriver.ExecutableQuery()
.
Do not hardcode or concatenate parameters: use placeholders and specify the parameters as a map through the .WithParameters()
method.
Person
nodes and a KNOWS
relationship between themvar result = await driver.ExecutableQuery(@"
CREATE (a:Person {name: $name})
CREATE (b:Person {name: $friendName})
CREATE (a)-[:KNOWS]->(b)
")
.WithParameters(new { name = "Alice", friendName = "David" })
.WithConfig(new QueryConfig(database: "<database-name>"))
.ExecuteAsync();
// Summary information
var summary = result.Summary;
Console.WriteLine($"Created {summary.Counters.NodesCreated} nodes in {summary.ResultAvailableAfter.Milliseconds} ms.");
Query a graph
To retrieve information from the database, use the Cypher clause MATCH
:
Person
nodes who know other personsvar result = await driver.ExecutableQuery(@"
MATCH (p:Person)-[:KNOWS]->(:Person)
RETURN p.name AS name
")
.WithConfig(new QueryConfig(database: "<database-name>"))
.ExecuteAsync();
// Loop through results and print people's name
foreach (var record in result.Result) {
Console.WriteLine(record.Get<string>("name"));
}
// Summary information
var summary = result.Summary;
Console.WriteLine($"The query `{summary.Query.Text}` returned {result.Result.Count()} results in {summary.ResultAvailableAfter.Milliseconds} ms.");
Close connections and sessions
Unless you created them with the using
keyword, remember to close all IDriver
and IAsyncSession
instances to release any resources still held by them.
await session.CloseAsync();
await driver.CloseAsync();
Glossary
- LTS
-
A Long Term Support release is one guaranteed to be supported for a number of years. Neo4j 4.4 is LTS, and Neo4j 5 will also have an LTS version.
- Aura
-
Aura is Neo4j’s fully managed cloud service. It comes with both free and paid plans.
- Cypher
-
Cypher is Neo4j’s graph query language that lets you retrieve data from the database. It is like SQL, but for graphs.
- APOC
-
Awesome Procedures On Cypher (APOC) is a library of (many) functions that can not be easily expressed in Cypher itself.
- Bolt
-
Bolt is the protocol used for interaction between Neo4j instances and drivers. It listens on port 7687 by default.
- ACID
-
Atomicity, Consistency, Isolation, Durability (ACID) are properties guaranteeing that database transactions are processed reliably. An ACID-compliant DBMS ensures that the data in the database remains accurate and consistent despite failures.
- eventual consistency
-
A database is eventually consistent if it provides the guarantee that all cluster members will, at some point in time, store the latest version of the data.
- causal consistency
-
A database is causally consistent if read and write queries are seen by every member of the cluster in the same order. This is stronger than eventual consistency.
- NULL
-
The null marker is not a type but a placeholder for absence of value. For more information, see Cypher → Working with
null
. - transaction
-
A transaction is a unit of work that is either committed in its entirety or rolled back on failure. An example is a bank transfer: it involves multiple steps, but they must all succeed or be reverted, to avoid money being subtracted from one account but not added to the other.
- backpressure
-
Backpressure is a force opposing the flow of data. It ensures that the client is not being overwhelmed by data faster than it can handle.
- transaction function
-
A transaction function is a callback executed by an
.ExecuteReadAsync()
or.ExecuteWriteAsync()
call. The driver automatically re-executes the callback in case of server failure. - IDriver
-
A
IDriver
object holds the details required to establish connections with a Neo4j database.