OK, so when dealing with async
in the .NET world, we're largely talking about using the await
keyword to allow the code to execute wherever it wants (in essence). But. Not everyone has the ability to use async
, so you need to be able to call it synchronously. You've done that already with the ConnectAsync()
call. The Wait()
basically is telling the code to wait for that bit to finish executing before carrying on.
So.
Let's tackle sync first.
The line you change is the var Result = query.ResultsAsync
one - to become... var Result = query.ResultsAsync.Wait()
Job done! So let's have a quick perusal of the other bits...
Now, I'm a tiny bit wondering if the code worked, as to my eyes, the cypher is invalid, I think you need the ()
around the Match
like so:
var query = client.Cypher
.Match("(n)") //Added ( ) here
.Return<string>("n");
OK, so now that should work. Next you will get JSON back, it'll be in the form defined here: Result formats - HTTP API - well similar and there are reasons we don't need to go into here...
The downside is that you have to parse that pesky JSON... I KNOW!
But - we can get around that, and that's kind of the point of the Neo4jClient
- so we don't have to see that stuff!
From here on in, we're going to be looking at a bit of 'abstract thoughts' - as I don't know what your n
looks like in the database. BUT let's assume it looks like this:
{
name: 'Lucas',
id: 1
}
We can create a class:
public class Data
{
public string name {get;set;}
public int id {get;set;}
}
and change our code to:
var query = client.Cypher
.Match("(n)") //Added ( ) here
.Return<Data>("n");
OR even BETTER!
var query = client.Cypher
.Match("(n)") //Added ( ) here
.Return(n => n.As<Data>());
2 things about the Data
class - 1 don't call it that, call it something that makes sense - for instance Person
would be way better here, or maybe Account
... Data
is terrible :o
The second thing is that the current implementation of Data
uses lowercase properties - which is C# naughtiness. So, 2 options here.
The first, and my preferred is to use UpperCamelCase for your properties when you store them, so your code has no translation steps. The second is to use [JsonProperty]
so your class could look like:
public class Person // Name changed!!
{
public string Name {get;set;}
public int Id {get;set;}
}
or
public class Person // Name changed!!
{
[JsonProperty("name")]
public string Name {get;set;}
[JsonProperty("id")]
public int Id {get;set;}
}
Don't worry - we're nearly done. I said we'd start with sync, and so let's end with async
You can actually modify your code to be async
, by making the Main
method async... so. let's put it ALL together:
public static async Task Main(string[] args) // Change here!!
{
var client = new BoltGraphClient("bolt://192.168.0.224:7687", "test0", "test0");
await client.ConnectAsync(); // awaiting here
var query = client
.Cypher
.Match("(n)")
.Return(n => n.As<Person>()); //Using 'Person' class
var result = await query.ResultsAsync; //Awaiting here
Console.WriteLine(result);
Console.ReadLine();
}
The last bit is upon us!
Dealing with the results
var
is a blessing and a curse, in the good/bad old days you'd have had to be explicit, which would have made it a bit clearer as to what you get from this. So:
var result = await query.ResultsAsync;
is actually:
IEnumerable<Person> result = await query.ResultsAsync;
The T
of the IEnumerable
comes from the .Return
bit - so - in your very first code for example, T
was string
.
Aaaanyhews - now we have an IEnumerable<Person>
if you try to WriteLine
it, you'll end up with something like:
System.Collections.IEnumerable{T}
being written out, which is not helpful. The easiest thing to do is a foreach
and just write your results out like this:
foreach(var result in results)
{
Console.WriteLine($"Name: {result.Name}, Id: {result.Id}");
}
So.
All the code.
public class Person
{
public string Name {get;set;}
public int Id {get;set;}
}
public static async Task Main(string[] args) // Change here!!
{
var client = new BoltGraphClient("bolt://192.168.0.224:7687", "test0", "test0");
await client.ConnectAsync();
var query = client
.Cypher
.Match("(n)")
.Return(n => n.As<Person>());
var result = await query.ResultsAsync;
foreach(var result in results)
{
Console.WriteLine($"Name: {result.Name}, Id: {result.Id}");
}
Console.ReadLine();
}
Phew!