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.Reflection.Assembly]::LoadFrom("C:\...\Newtonsoft.Json.6.0.3\lib\net40\NewtonSoft.Json.dll")
[System.Reflection.Assembly]::LoadFrom("C:\...\Neo4jClient.1.0.0.662\lib\net40\Neo4jClient.dll")
$neo = new-object Neo4jClient.GraphClient(new-object Uri("http://localhost:7474/db/data"))
$q=$neo.Cypher.Match("n").Return({param($m) $m});
with which I would mean to retrieve all nodes in the database. the Return()
method is shown in the example to require a lambda expression as a parameter, which in Powershell would be a code-block, however, I get the following error:
Cannot find an overload for "Return" and the argument count: "1". At line:1 char:1 + $q=$neo.Cypher.Match("n").Return({param($m) $m}); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodCountCouldNotFindBest
where am I going wrong?
* Update I *
with the explanation provided by @PetSerAl below, I've managed to get a little further, but I'm still stuck. below I will quote the write up (c#) and then show the equivalent powershell. first we declare a class
public class User
{
public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
my class differs a little
Add-Type -TypeDefinition "public class Project { public string Code; public string Name; public string Parent; public string Lifespan; }"
their Cypher
MATCH (user:User)
RETURN user
their c#
graphClient.Cypher
.Match("(user:User)")
.Return(user => user.As<User>())
.Results
now my cypher
MATCH (n:Project)
RETURN n
...and finally, my attempt at the powershell:
$exp = [System.Linq.Expressions.Expression]
$p = $exp::Constant("Project")
$fn = $exp::TypeAs($p, (new-object Project).GetType())
$return = $exp::Lambda([Func[Project]], $fn, $p)
$neo.Cypher.Match("n").Return($return)
but I get an error
Exception calling "Return" with "1" argument(s): "The expression must be constructed as either an object initializer (for example: n => new MyResultType { Foo = n.Bar }), an anonymous type initializer (for example: n => new { Foo = n.Bar }), a method call (for example: n => n.Count()), or a member accessor (for example: n => n.As().Bar). You cannot supply blocks of code (for example: n => { var a = n + 1; return a; }) or use constructors with arguments (for example: n => new Foo(n)). If you're in F#, tuples are also supported. Parameter name: expression" At line:1 char:1 + $neo.Cypher.Match("n").Return($return) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ArgumentException
which, for once, is actually very clear and understandable. so what I want is a method call e.g. n => n.Count()
and clearly did not achieve that.
help?
* Update II *
so, continuing on with the torturous path of neo4j from powershell, I've given @PetSerAl's second approach a stab and got a little further. here's what I managed to write:
$neopath = "C:\[...]\Neo4jClient.dll"
Add-Type -ReferencedAssemblies $neopath -TypeDefinition @"
using System;
using System.Linq.Expressions;
using Neo4jClient.Cypher;
public class Project {
public string Code;
public string Name;
public string Parent;
public string Lifespan;
};
public static class NeoExp {
public static readonly Expression<Func<Neo4jClient.Cypher.ICypherResultItem,Project>> GetProject = (n) => n.As<Project>();
}
"@
which now allows me to do:
$neo.Cypher.Match("n:Project").Return([NeoExp]::GetProject)
and that, miraculously, works! except it brings me back no data:
Results ResultsAsync Query Client
------- ------------ ----- ------
Neo4jClient.Cypher.CypherQ... Neo4jClient.GraphClient
and I know I have projects in the database... so what could the issue be now?
* Update III *
wow, so close but still not done. as per the latest suggestion from @PetSerAl. I tried:
$neo.Cypher.Match("n:Project").Return([NeoExp]::GetProject).get_Results()
which yielded an illuminating error:
Exception calling "get_Results" with "0" argument(s): "The graph client is not connected to the server. Call the Connect method first."
so that made it clear I first needed to do:
$neo.Connect()
also, I needed parentheses around the query's match clause:
$neo.Cypher.Match("(n:Project)").Return([NeoExp]::GetProject)
now I get 27 results back as expected in the .Results
field... however, the results are all blank. so I think maybe it has to do with the n.As<Project>()
where perhaps my class isn't defined properly and that fails. any thoughts?
* Update IV *
ok, got it. the Project
class needs to have properties, not fields:
public class Project {
public string Code { get; set; }
public string Name { get; set; }
public string Parent { get; set; }
public string Lifespan { get; set; }
};
and that's it. I have data. yea!!!
@PetSelAl: I owe you a beer