Search code examples
c#neo4jneo4jclient

How do I write this in Neo4jClient


Thanks to Dave Bennett, I have a great Neo4j query that provides the results I need. I need to get this to work in Neo4JClient. Here's my working Neo4j query:

`// Composite Tile with related users
match (t:Tile{summary:"Test 1"})<-[:ASSIGNED_TO]-(u:User)
with {summary: t.summary,
        id:             t.id, 
        sprint_id:      t.sprint_id, 
        size:           t.size,
        percent_done:   t.percent_done,
        color:          t.color_id,
        description:    t.description,
        queue_id:       t.queue_id,
        swimlane_id:    t.swimlane_id,
        icons:          t.icons, 
        order:          t.order,
        assignees: collect(u)} as tile
RETURN collect(tile) as tiles`

Visual Studio and/or Neo4jClient is not very happy with my attempt:

var compositeTile = client.Cypher
                .Match("(t:Tile)<-[:ASSIGNED_TO]-(u:User)")
                .Where((Tile t)=> t.summary == tile.summary)
                .With( {
                        summary:        t.summary, 
                        id:             t.id, 
                        sprint_id:      t.sprint_id,
                        size:           t.size,
                        percent_done:   tile.percent_done,
                        color:          t.color,
                        description:    t.description, 
                        queue_id:       t.queue_id, 
                        swimlane_id:    t.swimlane_id,
                        icons:          t.icons, 
                        Order:          t.order,
                        assignees:      collect(u)
                       } as tile)
                .return collect(tile) as tiles;

It just throws lots of red squiggly lines, I suspect because I'm not formatting the .with statement correctly. I haven't been able to find an example, so I'm asking here. How do I do this correctly in Neo4jClient?


Solution

  • So, two answers to your question - the first is that the .With statement takes a string as a parameter, so you just need to wrap your text with " (or @" if you want to keep the formatting). The second answer is more of a problem for you though:

    It's not possible to do what you're trying to do with Neo4jClient - at the moment it doesn't allow you to create anonymous types. It's not able to deserialize the content. I thought it might be a quick fix, but it seems like it would be more involved. So, what we're looking at here is a change of the query.

    I presume you have a class called Tile with the properties you're after. So I would change the query to something like this:

    client.Cypher
        .Match("(t:Tile)<-[:ASSIGNED_TO]-(u:User)")
        .Where((Tile t) => t.summary == tile.summary)
        .Return((t,u) => new { 
            Tile = t.As<Tile>(),
            User = u.CollectAs<User>()
        });
    

    Which will give you a C# anonymous type with a Tile and an IEnumerable<Node<User>> elements, obviously you want the Users in your Tile, so you can then parse the result:

    var tiles = new List<Tile>();
    foreach (var result in results)
    {
        var tile = result.Tile;
        foreach (var user in result.Users)
            tile.users.Add(user.Data);
        tiles.Add(tile);
    }
    

    One thing you might find is that you need to initialize the Users collection, so either add Users = new List<User>() to your Tile constructor, or just before parsing the data.