beast
beast

Reputation: 183

Dynamically using params for relationship in Neo4jClient

I am trying to use params to pass in relationship types dynamically with Neo4jclient but it didn't seem to work. Is this possible? Or what would be the equivalent? Basically I am trying to write a utility method to relate two nodes together by simply passing in two node Id and a relationship. I could potentially hard coded it but I am afraid that is against the best practice and vulnerable to injections. Thanks.

    public static async Task<string> AddEdge(string node1Id, string relatioinship, string node2Id, bool directed = false)
    {

            await NeoClient.Cypher
                    .Match("(n1)", "(n2)")
                    .Where((BaseObject n1) => n1.Id == node1Id)
                    .AndWhere((BaseObject n2) => n2.Id == node2Id)
                    .CreateUnique("n1-[:{sRelationName}]->n2")
                    .WithParams(new {sRelationName = relatioinship})
                    .ExecuteWithoutResultsAsync();
            return node1Id;
    }

Upvotes: 0

Views: 277

Answers (1)

Charlotte Skardon
Charlotte Skardon

Reputation: 6280

I don't think you can create a relationship name via parameters, the only way I've ever seen this done in C# is to to use string.Format for the .CreateUnique.

If you're worried about injection, one solution could be to use an Enum, so:

public enum Relationships { Rel_One, Rel_Two }

public static async Task<string> AddEdge(string nodeId1, Relationships relationship, string nodeId2)
{
    if(!Enum.IsDefined(typeof(Relationships), relationship))
        throw new ArgumentOutOfRangeException("relationship", relationship, "Relationship is not defined.");

That way if someone tries to pass in a relationship you're not using i.e. trying something like AddEdge("blah", (Relationships) 200, "blah2"); you can ignore it.

One nice thing you get from this is that you can use the enum directly in your format:

...CreateUnique(string.Format("n1-[:{0}]-n2", relationship))

provided you name your values in the Relationships enum as you want them:

public enum Relationships {
    HAS_A,
    IS_A
    //etc
}

Another bonus is that you don't have to worry about misspelling, as you can use the Relationships enum throughout your code for querying.

Upvotes: 2

Related Questions