Using Neo4j Graph DB With C#.NET

By | July 22, 2012

In the following example I’ll explain how to access the Neo4j database with the Neo4jClient. I’ve used both components in a project and was very satisfied.

Information about Neo4j: http://neo4j.org/
Information about Neo4jClient: http://hg.readify.net/neo4jclient/wiki/Home

For this demo I created an entity class called Person. This class will be represented in Neo4j as a node.

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

Then I defined two relationship classes. An relationship has to inherit from Neo4jClient.Relationship and implement Neo4jClient.IRelationshipAllowingSourceNode<>, Neo4jClient.IRelationshipAllowingTargetNode<>.
The both interfaces are defining the direction and the entity types of the start and end node of the relationship. The following code contains two relationship classes called “KnowsRelationship” and “HatesRelationship”. Both can be used only with the person class. (Start and end node)

If a relationship has attributes, then your class needs to inherit from the generic Relationship class. The generic type is your data class. In my example “HatesData”.

public class HatesData
{
    public string Reason { get; set; }

    public HatesData()
    { }

    public HatesData(string reason)
    {
        this.Reason = reason;
    }
}

public class KnowsRelationship : Relationship, IRelationshipAllowingSourceNode<Person>,
    IRelationshipAllowingTargetNode<Person>
{
    public static readonly string TypeKey = "KNOWS";

    public KnowsRelationship(NodeReference targetNode)
    : base(targetNode)
    { }
 
    public override string RelationshipTypeKey
    {
        get { return TypeKey; }
    }
}

public class HatesRelationship : Relationship<HatesData>, IRelationshipAllowingSourceNode<Person>,
IRelationshipAllowingTargetNode<Person>
{
    public static readonly string TypeKey = "HATES";

    public HatesRelationship(NodeReference targetNode, HatesData data)
        : base(targetNode, data)
    { }

    public override string RelationshipTypeKey
    {
        get { return TypeKey; }
    }
}

Now we have an entity called person and two relationship types which can be used for defining relationship between all person objects.
Now let’s create some sample data. There is no need to set up the data structure like in a RDBMS. The Neo4jclient serializes the objects and sends them to the Neo4j services. Neo4j parses the data and creates nodes and all relationships between them on the fly.

// Init
var client = new GraphClient(new Uri("http://localhost:7474/db/data"));
client.Connect();
         
// Create entities
var refA = client.Create(new Person() { Name = "Person A" });
var refB = client.Create(new Person() { Name = "Person B" });
var refC = client.Create(new Person() { Name = "Person C" });
var refD = client.Create(new Person() { Name = "Person D" });

// Create relationships
client.CreateRelationship(refA, new KnowsRelationship(refB));
client.CreateRelationship(refB, new KnowsRelationship(refC));
client.CreateRelationship(refB, new HatesRelationship(refD), new HatesData("Crazy guy")));
client.CreateRelationship(refC, new HatesRelationship(refD), new HatesData("Don't know why...")));
client.CreateRelationship(refD, new KnowsRelationship(refA));

And here is the result visualized with the Neo4j web admin.
Graph Sample Data

Now the cool thing is, you can query the data very easy. Let’s select all
who hates the “Person D”.
(I used in this example the Cypher query language.)

var query = new Neo4jClient.Cypher.CypherQuery(
    "start n=node(8) match n<-[r:HATES]-e return e.Name as Name;", 
    new Dictionary<string, object>(), 
    CypherResultMode.Projection);

var result = client.ExecuteGetCypherResults<Person>(query);

This query will return the person "B" and "C". (Like displayed in the picture above. Id 6 and 7.)

Have fun with Neo4j and Neo4jClient ;)

  • Pingback: Neo4j and Neo4jClient dis and dat | Selfelected

  • LosManos

    Did you verify that Reason was persisted in the database? – I am gratefully following your code but don’t get the property persistence to… persist.

  • DaMi

    You’re right! I corrected my mistake. Check my code. If your relationship has attributes, then you must inherit from the generic relationship class.

  • Saad

    There should be no brackets in Line 14 & 15 under the
    // Create relationships