How to deserialize a relationship from a Cypher query, retaining a dynamic relationship type?

28 Views Asked by At

Let's start with an example data set. There are 2 nodes and 2 relationships with differing relationship types between them. Both nodes and relationships have properties. Don't focus too much on the semantics, this is derived from a use case I cannot show here directly.

create (a:AlphaNode {name: "Alice"} )
create (b:BetaNode {name: "Bob"} )
create (a)-[:HAS {really: false} ]->(b)
create (a)-[:NEEDS {timespan: 42} ]->(b)

Now, I would like to run a query along the following lines:

match (a:AlphaNode)-[r:HAS|NEEDS]->(b:BetaNode)
// where etc ... (not important in the example)
return a, r, b

This will return 2 result sets, where the nodes are identical, only the relationship denoted by r will differ between the result sets.

My C# code using Neo4jClient should look like this:

client.Cypher
    .Match("(a:AlphaNode)-[r:HAS|NEEDS]->(b:BetaNode)")
    .ReturnDistinct((a, r, b) => new
    {
        A = a.As<AlphaNode>(),
        R = r.As<SomeRelationship>(),
        B = b.As<BetaNode>()
    })
    // .ResultAsync etc. (not important, here)
    ;

Now, I'm running into problems with SomeRelationship. Surely, I could make it a POCO/DTO, but then I wouldn't have access to the relationship type (HAS or NEEDS). I can't find a good hint or example in the docs and all I've found are hints towards the classes Relationship, RelationshipInstance, RelationshipReference (which would have a relationship type, but this is not read from the database, but rather fixed by class inheritance), but I can't really make them (or their descendants, to be more precise) work like this (even for a single relationship, but the dynamics are the actual point, here).

Is there a way to do this more cleanly with a dynamic relationship POCO than with some weird inheritance that is mainly there in order to replace a constructor with a parameterless one? I think the intentions for these classes are a bit different from what I expect. Don't get me wrong, I'd love to inherit a relationship-ish base class, but the base class would have to provide the relationship type from the response and have a parameterless constructor in the first place.

0

There are 0 best solutions below