New Nuget Package for Neo4j Users - Neo4jClient.Extension

The defacto standard for .net users of Neo4j is the Neo4jClient nuget package, if you don’t have that, you’re basically rolling your own connection code, in some cases you might need to, but most of the time, the client will work well.

Today I was adding Neo4jClient to a new project, and searched via the Nuget package UI and up popped Neo4jClient.Extension, so, I went to the github repo, read the .md file and thought - I’ll download that bad boy and give it a go.

The general gist is to be able to pass things like your actual entities to the client without needing to write the Cypher, thereby adding even more type safety to your code, so instead of:

Client.Cypher.Merge(string.Format("(n:Label {{item}}.Id = {0})", entity.Id));

You can now just put in:


Which certainly prevents typos. I’ll describe a bit more about it below, but the TL:DR of it is, whilst it’s in it’s early stages, it’s worth looking at for a .net developer, in particular with a new project. There are some issues to be aware of (see the bottom of the post) but all in all I look forward to seeing how this progresses.

Attributes Everywhere!

Neo4jClient.Extension uses attributes for most of it’s core functionality.


I like the [CypherLabel] attribute a lot, it works well for simple cases, and is a neat way of putting labels in the code, the downside would come from wanting to add extra more dynamic labels, so you might have a class called Location looking something like this:

class Location {
    public string Name { get; set; }

But you couldn’t subsequently put something in the DB with (n:Location:USA) as there is no way to add the ‘USA’ label.


Here we can do searches in a simpler fashion to the old way, so instead of:

Client.Match("(n:Model {Id:{myParam}.Id})").Return(n => n.As<MyObj>());

we instead just do:

Client.Cypher.MatchEntity(model, "n").Return(n => n.As<MyObj>());

Note, I’ve defined the ‘n’ parameter name in the MatchEntity call, if I left that out, the param name would (at present) be the lowercased name of the label.


These are the main guts and where the work is really showing, the cool thing here is it removing the complexity and nightmare of curly brace nesting. Basically, the CypherMerge attribute defines the ‘key’ the Merge will work from, generally this will be the ‘Id’ property. The MergeOnCreate attribute is applied to all the attributes you would want to be created as part of the ‘ON CREATE’ bit of a MERGE query, and quite obviously the MergeOnMatch attribute is for the ON MATCH bit.

One thing to consider with the use of these attributes (and it affects the ‘CypherMatch’ one as well) is that you can only have one Merge/Create version, so if you decide you want to merge properties 1,2,3 one time and 4,5,6 another, you’re going to have to revert to the old .Merge technique for at least one of those cases. It’s not a huge issue because in at least one of the cases you’ve saved a bucket load of curly brace potential problems.

Some issues

It’s early days, and only version but these are worth noting in case you want to use the package.

Case changing of Property names

For some reason the case of the properties in my classes is changed so the first character is lowercase, which is not something I’m overly pleased with, it’s not ‘end of the world’ type stuff, but I’m wary of code that doesn’t do what I expect, and I expect if I have a property called ‘Name’ that it will be stored as ‘Name’ in the DB.


If you use any special characters in your labels, such as ‘/’, ‘ ‘ (space) or just the ` character you’ll run into issues, there is a pull request to fix this, so hopefully not an issue for long


You can apply the CypherLabel attribute to a property (and a CypherMerge* attribute to a class) but in both cases they won’t do anything.

Print | posted @ Wednesday, November 26, 2014 1:47 PM

Comments on this entry:

No comments posted yet.

Post A Comment