
Neo4j Driver Dotnet Skill
Implement correct Neo4j .NET Driver v6 patterns in C# apps—sessions, transactions, mapping, and batching.
Install
npx skills add https://github.com/neo4j-contrib/neo4j-skills --skill neo4j-driver-dotnet-skillWhat is this skill?
- Official Neo4j.Driver NuGet guidance for v6 on .NET 8/9/10
- Decision table for ExecutableQuery vs managed vs explicit transactions
- DI recipes: AddSingleton IDriver, session-per-unit-of-work, shutdown hooks
- 20+ common mistake/fix pairs including async void and ClientException ordering
- UNWIND batching, record access, temporal mapping, and Preview object mapping APIs
Adoption & trust: 1 installs on skills.sh; 80 GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
Recommended Skills
Supabase Postgres Best Practicessupabase/agent-skills
Lark Baselarksuite/cli
Convex Migration Helperget-convex/agent-skills
Neon Postgresneondatabase/agent-skills
Firebase Firestore Standardfirebase/agent-skills
Postgresql Table Designwshobson/agents
Journey fit
Primary fit
Build → Backend is where database client wiring, DI, and query execution patterns belong for a .NET service talking to Neo4j. Backend covers driver lifecycle and data access—not Cypher authoring (separate skill) or version migrations.
Common Questions / FAQ
Is Neo4j Driver Dotnet Skill safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Neo4j Driver Dotnet Skill
# neo4j-driver-dotnet-skill Official Neo4j .NET Driver v6 — usage guide for C# / .NET applications connecting to Neo4j. ## Topics covered - **Install** — `Neo4j.Driver` NuGet package, package variants - **Driver lifecycle** — `IDriver` singleton, `await using`, `VerifyConnectivityAsync` - **DI registration** — `AddSingleton<IDriver>`, shutdown hook, session-per-unit-of-work - **API selection** — `ExecutableQuery` vs managed vs explicit transactions decision table - **ExecutableQuery** — fluent builder, `WithParameters`, `WithConfig`, `WithMap`, `EagerResult` deconstruct - **Managed transactions** — `ExecuteReadAsync`/`ExecuteWriteAsync`, retry safety, async void trap - **IResultCursor** — `ToListAsync`, `FetchAsync` loop, `ConsumeAsync`, `SingleAsync` - **Record access** — `.Get<T>()`, `.As<T>()`, null safety, absent key handling - **Type mapping** — Cypher → .NET table, temporal types, `ElementId` lifetime - **UNWIND batching** — anonymous type arrays, `Dictionary<string,object>` - **Object mapping** — `AsObject<T>`, `AsObjectsAsync<T>`, C# record types (Preview API) - **Error handling** — exception hierarchy, `ClientException` ordering, rollback safety - **Common mistakes** — 20+ mistake/fix table ## Version / compatibility Driver v6, .NET 8/9/10. Docs: https://neo4j.com/docs/dotnet-manual/current/ ## Not covered - Cypher query authoring → `neo4j-cypher-skill` - Driver version upgrades → `neo4j-migration-skill` ## Install ```bash dotnet add package Neo4j.Driver ``` # Object Mapping and Repository Pattern ## Preview Mapping API All mapping extension methods live in `Neo4j.Driver.Preview.Mapping`. Without this using directive, `AsObject<T>()` and `AsObjectsAsync<T>()` cause CS1061 compile errors. ```csharp using Neo4j.Driver.Preview.Mapping; // REQUIRED ``` ## AsObject<T>() — Single Record ```csharp public record Person(string Name, int Age); var result = await driver .ExecutableQuery("MATCH (p:Person) RETURN p.name AS name, p.age AS age") .WithConfig(new QueryConfig(database: "neo4j")) .ExecuteAsync(); var person = result.Result[0].AsObject<Person>(); // RETURN key names map to property names (case-insensitive by default) // 'name' → Name, 'age' → Age ``` C# `record` types work well — positional constructor parameters are matched by name. ## Blueprint Mapping (anonymous types) ```csharp var person = result.Result[0].AsObjectFromBlueprint(new { name = "", age = 0 }); Console.WriteLine(person.name); // "Alice" Console.WriteLine(person.age); // 21 ``` ## Lambda Mapping ```csharp var person = result.Result[0].AsObject( (string name, int age) => new { Name = name, Age = age, BirthYear = 2025 - age }); ``` ## AsObjectsAsync<T>() — Bulk Mapping ```csharp var (people, summary, _) = await driver .ExecutableQuery("MATCH (p:Person) RETURN p.name AS name, p.age AS age") .WithConfig(new QueryConfig(database: "neo4j")) .AsObjectsAsync<Person>(); // maps all records; returns EagerResult<IReadOnlyList<Person>> ``` --- ## Repository Pattern Example ```csharp public interface IPersonRepository { Task<IReadOnlyList<Person>> FindByNamePrefixAsync(string prefix, CancellationToken ct = default); Task CreateAsync(Person person, CancellationToken ct = default); Task BulkCreateAsync(IEnumerable<Person> people, CancellationToken ct = default); } public class PersonRepository(IDriver driver, string database = "neo4j") : IPersonRepository { public async Task<IReadOnlyList<Person>> FindByNamePrefixAsync( string prefix, CancellationToken ct = default) { var (records, _, _) = await driver .ExecutableQuery(@" MATCH (p:Person) WHERE p.name STARTS WITH $prefix RETURN p.name AS name, p.age AS age") .WithParameters(new { prefix }) .WithConfig(new QueryConfig(database, RoutingControl.Readers)) .ExecuteAsync(ct); return records .Sel