I\'m following this little write up: https://github.com/Readify/Neo4jClient/wiki/cypher but I\'m doing it from Powershell. so what I have so far is
[System.
I know this is not exactly what you're asking, and might not even be what you want, but you could create your own C# class right inside PowerShell using Add-Type. It might be easier to implement it that way and provide simple methods you can use within the PowerShell code if what you're writing relies on a lot of C#-specific things.
This example is taken straight from the link above:
$source = @"
public class BasicTest
{
public static int Add(int a, int b)
{
return (a + b);
}
public int Multiply(int a, int b)
{
return (a * b);
}
}
"@
Add-Type -TypeDefinition $source
[BasicTest]::Add(4, 3)
$basicTestObject = New-Object BasicTest
$basicTestObject.Multiply(5, 2)
There are two problems with Return
method:
ScriptBlock
. So, you have to create expression tree by hands or use string
overload.string
overload does not allows PowerShell to infer generic parameter for method, and PowerShell syntax does not allows to specifying generic parameter explicitly. So, PowerShell can not call string
overload of Return
method directly. You have to use some workaround to call it, for example, call it thru Reflection
.Sample how can you create a simple expression tree ((a,b) => a*2+b
) in PowerShell:
# First way: messing with [System.Linq.Expressions.Expression]
$a=[System.Linq.Expressions.Expression]::Parameter([int],'a')
$b=[System.Linq.Expressions.Expression]::Parameter([int],'b')
$2=[System.Linq.Expressions.Expression]::Constant(2)
$Body=[System.Linq.Expressions.Expression]::Add([System.Linq.Expressions.Expression]::Multiply($a,$2),$b)
$Sum=[System.Linq.Expressions.Expression]::Lambda([Func[int,int,int]],$Body,$a,$b)
$Sum
# Second way: using help of C#
Add-Type -TypeDefinition @'
using System;
using System.Linq.Expressions;
public static class MyExpression {
public static readonly Expression<Func<int,int,int>> Sum=(a,b) => a*2+b;
}
'@
[MyExpression]::Sum
The best I can tell is that you're using it wrong. Your object structure should be your Neo4jClient
object, which should then have a few properties and methods. I am pretty sure that Return
is a property, not a method. So I'm thinking something more like:
$neo = new-object Neo4jClient.GraphClient(new-object Uri("http://localhost:7474/db/data"))
$neo.Cypher.Match = "n"
$neo.Cypher.Return = {param($m) $m}
$q = $neo.Cypher.Results()
There you create your object, you define the Match
filter, define what you want it to return (everything from the looks of it), and then store the results in the $q
variable. I'm pretty sure that should be the same as:
SELECT * FROM Uri("http://localhost:7474/db/data")) WHERE "n"
I also kind of wonder about your Match
criteria, since they seem to be specifying property/value pairs in their examples and you just give one of the two. If that fails I would strongly suggest doing a $neo.Cypher | Get-Member
to see what properties you have, what they're typed as, and what methods you have.
Edit: Ok, so I did look at the link. I also downloaded the libraries, loaded them into PowerShell, and looked at the .Net objects. Return is indeed a method, and the overloads for it are ridiculous. There are 37 overloads for it, the longest of which is almost 750 characters. Most of them are ICypherResultItem
expressions, but the simplest is (string identity)
. Might I suggest simply trying Return("*")
?
a million thanks to @PetSerAl who explained the problem well in its essence, and who held my hand through its resolution.
to restate, the problem is that Powershell has no built-in mechanism to call generic methods and the Neo4jClient library's .Return
method overloads are all generic. Specifically, Powershell provides no means of supplying the type of the method.
so there are several ways to solve this:
one solution is to use reflection to make the call, but the task is a bit tricky. thankfully the approach has been tackled by a project available on tech net. see: https://gallery.technet.microsoft.com/scriptcenter/Invoke-Generic-Methods-bf7675af
the second solution suggested in @PetSerAl's reply needed a little help but with @ChrisSkardon's help I got it to work. see here: Constructing a method call
and the third solution (see the Updates in the original post) which relies on creating a c# class with a method where the generic method can be called
I expect to be documenting this solution in the wiki for Neo4jClient and I hope the effort documented here is helpful to others. Thanks again @PetSerAl for all your help