1
votes

I am writing a .NET airport application using neo4j for the first time. I have an API and can get my objects (Airports in this case) that are in the database. I can also create new Airports with

public void Post([FromUri]string name, [FromUri]string code, [FromUri]string city, [FromUri]string state)
{
    string query = "(:Airport{name:'" + name + "',code:'" + code.ToUpper() + "',city:'" + city + "',state:'" + state.ToUpper() + "'})";
    var q = WebApiConfig.GraphClient.Cypher.Create(query);
    q.ExecuteWithoutResults();
}

That works fine. But I also want to make sure that the Airport does not already exist in the database. So I have tried to add in the code:

var existing = WebApiConfig.GraphClient.Cypher.Match("(a:Airport)")
            .Where((Airport a) => a.Code.Equals(code.ToUpper()))
            .Return(a => a.As<Airport>());

But when I run this code section it always throws a SyntaxException. I think that it is in the construction of the where clause.

My Airport class is

public class Airport
{
    public string City { get; set; }
    public string State { get; set; }
    public string Code { get; set; }
}

The current resource I am using is https://github.com/Readify/Neo4jClient/wiki/cypher.

Two questions:

  1. What am I missing here?
  2. Are there other resources out there that would help me out?

Thank you

1
hi Michael - what's the Syntax exception you're getting?Charlotte Skardon
Ahh no, I think I know what it is - I'll answer in a few minsCharlotte Skardon

1 Answers

1
votes

The SyntaxException is being thrown because Neo4jClient doesn't know how to deal with .Equals - if you take your query and look at the existing.Query.DebugQueryText you'll see it output (I'm passing in 'lax' as code):

MATCH (a:Airport)
WHERE a.Code"lax"
RETURN a

The SyntaxException comes from the WHERE a.Code"lax" - so you need to firstly change to using the == operator instead:

var existing = gc.Cypher.Match("(a:Airport)")
        .Where((Airport a) => a.Code == code.ToUpper())
        .Return(a => a.As<Airport>());

Now if we look at the QueryDebugText we get:

MATCH (a:Airport)
WHERE (a.Code = "lax")
RETURN a

But "lax" is lower case - we put ToUpper() there, so it should be "LAX" right??

A subtle nuance of Neo4jClient is that it needs to have the details as they need to be for the query, so doing:

code = code.ToUpper();
var existing = gc.Cypher.Match("(a:Airport)")
        .Where((Airport a) => a.Code == code)
        .Return(a => a.As<Airport>());

will generate:

MATCH (a:Airport)
WHERE (a.Code = "LAX")
RETURN a

You can use methods like ToUpper but you end up having to put them in a string.Format or interpolation:

var existing = gc.Cypher.Match("(a:Airport)")
        .Where($"(a.Code = \"{code.ToUpper()}\")")
        .Return(a => a.As<Airport>());

Which is a pain, as you need to remember the \" and open/close parentheses.

General tip is to always look at the DebugQueryText to see what is being generated.

Your second question as to more resources - I'm afraid there isn't :(