Reputation: 793
My VB.NET code was working wonderfully using Imports Neo4j.v1 and Neo4j 3.x
I've upgraded to Neo4j 4.01 server on my laptop (Community Editon) and can connect and query successfully in Neo4j Desktop. I used NUGet to remove the old Neo4j reference and add Neo4j 4.01 driver. The code no longer works.
Imports Neo4j.Driver
Dim D = GraphDatabase.Driver(uri:=Neo4Lib.Neo4ConnectionString, authToken:=AuthTokens.Basic(Neo4Lib.Neo4UserName, Neo4Lib.Neo4Pswd))
Using session = D.Session()
'query database
Dim rslt = session.run(CQ)
.... processing ...
End Using
It crashes are the Using session=D.Session() line with an error of
Overload resolution failed because no accessible 'Session' accepts this number of arguments.
I've studied the background materials at https://neo4j.com/docs/driver-manual/current/session-api/simple/ but cannot see the problem. I've had similar issues with Neo4j v4 on Azure with Python code.
Would appreciate suggested fixes.
Upvotes: 0
Views: 213
Reputation: 6270
The original problem stems from the fact that the old code you were using had the Sync code in the Neo4j.Driver
package, from 4.x
onwards the Neo4j.Driver
package contains only Async code.
There is a Neo4j.Driver.Simple
package (https://www.nuget.org/packages/Neo4j.Driver.Simple/) which would act like the 1.7x
versions did. As a quick side note - it's not possible to delete a package from Nuget - once it's been published it's always there - the 1.7.2
one is here: https://www.nuget.org/packages/Neo4j.Driver/1.7.2 - at the worst - it could be hidden - but in that case you would just have to ask for the version explicitly. So you shouldn't have to worry about keeping older versions around.
I've written 3 examples (below) which show using the new driver from VB from a selection of angles, using just the Neo4j.Driver
package and using Neo4j.Driver.Simple
package. All 3 of them need the following Import
statements (and these are basic Console
apps). Also - none of them need the ConfigBuilder
parameter.
'The imports
Import System
Import Neo4j.Driver
Import System.Threading.Tasks
Neo4j.Driver.Simple
versionAs this is the closest to the 1.7.2
version - I'll put this first:
Sub Main
SyncVersion()
End Sub
Sub SyncVersion()
Dim query = "MATCH (m:Movie) RETURN m"
'NB. Driver could be in a 'Using' on this.
Dim driver = GraphDatabase.Driver(uri:="neo4j://localhost:7687", authToken:=AuthTokens.Basic("neo4j", "neo"))
'Open the session
Using session = driver.Session()
Dim result As IResult = session.Run(query)
For Each record As IRecord In result
Console.WriteLine(record("m").Properties("title"))
Next
End Using
'Close the driver
driver.Dispose()
End Sub
The benefits of this are that it should closely match your codebase, with minimal changes for you.
Neo4j.Driver
package - using AsyncThis route does need you to use Async / Await:
'Note - This is also declared as Async
Async Sub Main
AsyncVersion()
End Sub
Async Function AsyncVersion() As Task
Dim query = "MATCH (m:Movie) RETURN m"
Dim driver = GraphDatabase.Driver(uri:="neo4j://localhost:7687", authToken:=AuthTokens.Basic("neo4j", "neo"))
'Open the session
Dim session = driver.AsyncSession()
'Get the result cursor
Dim result As IResultCursor = Await session.RunAsync(query)
'Loop through it
While Await result.FetchAsync()
Console.WriteLine(result.Current("m").Properties("title"))
End While
'Close the session
Await session.CloseAsync()
'Close the driver
Await driver.CloseAsync()
End Function
Downsides are that you have to control the lifecycle of the Session
and Driver
objects yourself - i.e. you can't just use a Using
statement :/
Neo4j.Driver
package - Async code in a Sync wayThis is the worst case scenario, as it involves you basically sync-ifying async code, using .Wait()
and some very clunky ForEach
ing - but I thought it would fill up the examples:
'Not Async this time
Sub Main
SyncWithAsync()
End Sub
Sub SyncWithAsync()
Dim query = "MATCH (m:Movie) RETURN m"
Dim driver = GraphDatabase.Driver(uri:="neo4j://localhost:7687", authToken:=AuthTokens.Basic("neo4j", "neo"))
'Open the session
Dim session = driver.AsyncSession()
'Get the result cursor
Dim resultTask As Task(Of IResultCursor) = session.RunAsync(query)
resultTask.Wait()
'Loop through it, but as we're 'syncing' an async, we need to wait for 'fetch' to work.
Dim fetchTask = resultTask.Result.FetchAsync()
fetchTask.Wait()
While fetchTask.Result
Console.WriteLine(resultTask.Result.Current("m").Properties("title"))
fetchTask = resultTask.Result.FetchAsync()
fetchTask.Wait()
End While
'Close the session
session.CloseAsync().Wait()
'Close the driver
driver.CloseAsync().Wait()
End Sub
You still have to manage the life cycle of the Session
and Driver
instances.
Hope that helps
Upvotes: 1
Reputation: 793
The solution: the session was run asynch and, as Hursey suggested above, it did require a ConfigBuilder argument, even though it was "Nothing". The return is different than my code for Neo4j 3.x, so I need to write new parsing code ... but I now have something to work with!
Imports Neo4j.Driver
CQ={neo4j cypher query}
Dim D = GraphDatabase.Driver(uri:=Neo4Lib.Neo4ConnectionString, authToken:=AuthTokens.Basic(Neo4Lib.Neo4UserName, Neo4Lib.Neo4Pswd))
Dim cb As ConfigBuilder = Nothing
Using session = D.AsyncSession(cb)
'query database
Dim rslt As System.Threading.Tasks.Task = session.RunAsync(CQ)
{process IResultCursor}
End Using
Upvotes: 0