DavidReid
DavidReid

Reputation: 449

neo4jclient to POCO objectGraph

I'm starting to play with neo4jclient, and although I have found the wiki pages which show pulling out nodes etc. I'm a little confused how to take a slighlty more complex structure from the graphDB and reconstruct it into my POCO objects.

As an example, say I have the following graph:

graphDB

And I have the following classes:

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

    public List<Sport> watches { get; set; }
    public List<Sport> plays { get; set; }

}

public class Sport
{
    public string name { get; set; }

    public GoverningBody governingBody { get; set; }
}

public class GoverningBody
{
    public string name { get; set; }
}

Could somebody give me the c# code I would need to use to pull out "David", along with the sports he plays and the governing body for that sport. The end goal would be that the Person, Sport(s) and GoverningBody objects would all be populated so that I can use them as normal within the C# code.

Thanks David

Upvotes: 0

Views: 240

Answers (2)

Charlotte Skardon
Charlotte Skardon

Reputation: 6280

This is a very quick solution - you can create (in effect) an anonymous type in the With statement that you can parse into a result, for example, with the addition of a SportAndGovern class:

public class SportAndGovern
{
    public Sport Sport { get; set; }
    public GoverningBody Govern { get; set; }
}

You can execute this Cypher (I've not used parameterised stuff, you should) to get a person with a list of the sports they play - you do end up with duplicated Governing Bodies coming back, i.e. one for each Sport the person watches.

var query = Client.Cypher
    .Match("(p:Person {Name:'David'})")
    .OptionalMatch("(p)-[:PLAYS]->(s:Sport)<-[:GOVERNS]-(g:GoverningBody)")
    .With("p, Collect(Distinct {Sport: s, Govern: g}) as sportAndGovern")
    .Return((p, sportAndGovern) => new
    {
        Person = p.As<Person>(),
        SportAndGovern = Return.As<IEnumerable<SportAndGovern>>("sportAndGovern")
    });

Upvotes: 1

ceej
ceej

Reputation: 1893

This code should get you started

var userQuery = client.Cypher
    .Match("(n:Person { name: 'David'})-[:PLAYS]->(s:Sport)")
    .Return((n, s) => new
    {
        Peep = n.As<Person>(),
        Sports = s.CollectAsDistinct<Sport>()
    })
    .Results
    .FirstOrDefault();

var david = userQuery.Peep;
david.plays = userQuery.Sports.ToList();

SO looking at this in a little detail there are some points to note.

Firstly, client refers to an instance of Neo4jClient and assumes that you have previously initialised this.

Secondly, the query assumes that you only have one Person node where the name property has a value of "David".

The Return clause projects the query results into an Anonymous type. It uses the CollectAsDistinct method to return an IEnumerable<Sport> collection. This translates into COLLECT(distinct s) in Cypher to collect the Sport nodes.

Finally, it then users the anonymous type to build up a Person object to return.

Upvotes: 0

Related Questions