Reputation: 183
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
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