我跟着这个小小的写作:https://github.com/Readify/Neo4jClient/wiki/cypher,但我是从Powershell做的。所以到目前为止我所拥有的是
[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});
我将用它来检索数据库中的所有节点。示例中显示了Return()
方法,要求将lambda表达式作为参数,在Powershell中它将是一个代码块,但是,我收到以下错误:
无法找到"返回"和参数计数:" 1"。在 line:1 char:1 + $ q = $ neo.Cypher.Match(" n")。返回({param($ m)$ m}); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo:NotSpecified:(:) [],MethodException + FullyQualifiedErrorId:MethodCountCouldNotFindBest
我哪里错了?
*更新I *
根据@PetSerAl提供的解释,我已经设法进一步,但我仍然卡住了。下面我将引用写下来(c#),然后显示等效的powershell。首先我们声明一个类
public class User
{
public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
我的班级略有不同
Add-Type -TypeDefinition "public class Project { public string Code; public string Name; public string Parent; public string Lifespan; }"
他们的Cypher
MATCH (user:User)
RETURN user
他们的c#
graphClient.Cypher
.Match("(user:User)")
.Return(user => user.As<User>())
.Results
现在是我的密码
MATCH (n:Project)
RETURN n
......最后,我对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)
但是我收到了错误
异常通话&#34;返回&#34;用&#34; 1&#34;参数:&#34;表达式必须 被构造为对象初始化器(例如:n =&gt; new MyResultType {Foo = n.Bar}),一个匿名类型的初始化器(for 例如:n =&gt; new {Foo = n.Bar}),方法调用(例如:n =&gt; n.Count()),或成员访问者(例如:n =&gt; n.As()。Bar)。 您无法提供代码块(例如:n =&gt; {var a = n + 1; 返回; })或使用带参数的构造函数(例如:n =&gt; new FOO(N))。如果你在F#中,也支持元组。参数名称: 表达&#34;在行:1个字符:1 + $ neo.Cypher.Match(&#34; n&#34;)。返回($ return) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo:NotSpecified:(:) [],MethodInvocationException + FullyQualifiedErrorId:ArgumentException
这一次,实际上是非常明确和可以理解的。所以我想要的是方法调用,例如n => n.Count()
显然没有实现这一目标。
帮助?
*更新II *
所以,继续使用来自powershell的neo4j的曲折路径,我已经给@ PetSerAl的第二个方法刺了一下,然后再进一步。这是我设法写的:
$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>();
}
"@
现在允许我这样做:
$neo.Cypher.Match("n:Project").Return([NeoExp]::GetProject)
那,奇迹般地,有效!除了它让我没有数据:
Results ResultsAsync Query Client
------- ------------ ----- ------
Neo4jClient.Cypher.CypherQ... Neo4jClient.GraphClient
我知道我在数据库中有项目......那么现在的问题是什么呢?
*更新III *
哇,好近,但还没完成。根据@PetSerAl的最新建议。我试过了:$neo.Cypher.Match("n:Project").Return([NeoExp]::GetProject).get_Results()
产生了一个明显的错误:
异常调用&#34; get_Results&#34;用&#34; 0&#34;参数:&#34;图表 客户端未连接到服务器。首先调用Connect方法。&#34;
所以说清楚我首先要做的事情:
$neo.Connect()
另外,我需要围绕查询匹配子句的括号:
$neo.Cypher.Match("(n:Project)").Return([NeoExp]::GetProject)
现在我在.Results
字段中按预期收到了27个结果...但是,结果都是空白的。所以我想也许它与n.As<Project>()
有关,也许我的班级没有正确定义而且失败了。有什么想法吗?
*更新IV *
好的,明白了。Project
类需要具有属性,而不是字段:
public class Project {
public string Code { get; set; }
public string Name { get; set; }
public string Parent { get; set; }
public string Lifespan { get; set; }
};
就是这样。我有数据。酵母!!!
@PetSelAl:我欠你一杯啤酒
答案 0 :(得分:2)
Return
方法存在两个问题:
ScriptBlock
创建表达式树。因此,您必须手动创建表达式树或使用string
重载。string
重载不允许PowerShell推断方法的泛型参数,而PowerShell语法不允许显式指定泛型参数。因此,PowerShell无法直接调用string
方法的Return
重载。您必须使用一些变通方法来调用它,例如,通过Reflection
调用它。示例如何在PowerShell中创建简单的表达式树((a,b) => a*2+b
):
# 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
答案 1 :(得分:1)
我知道这并不是你所要求的,甚至可能不是你想要的,但你可以create your own C# class right inside PowerShell using Add-Type
。以这种方式实现它可能更容易,并提供可在PowerShell代码中使用的简单方法,如果您正在编写的内容依赖于大量C#特定的东西。
此示例直接来自上面的链接:
$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)
答案 2 :(得分:0)
我能说的最好的就是你错了。您的对象结构应该是您的Neo4jClient
对象,然后该对象应具有一些属性和方法。我很确定Return
是属性,而不是方法。所以我想的更像是:
$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()
在那里你创建了你的对象,你定义了Match
过滤器,定义了你希望它返回什么(从它的外观来看),然后将结果存储在$q
变量中。我很确定它应该与:
SELECT * FROM Uri("http://localhost:7474/db/data")) WHERE "n"
我也对你的Match
标准感到好奇,因为他们似乎在他们的例子中指定了属性/值对,你只需要给出其中一个。如果失败,我强烈建议您使用$neo.Cypher | Get-Member
查看您拥有的属性,他们输入的内容以及您拥有的方法。
编辑:好的,所以我确实看了一下这个链接。我还下载了库,将它们加载到PowerShell中,然后查看.Net对象。返回确实是一种方法,它的重载是荒谬的。它有37个重载,其中最长的是近750个字符。其中大多数是ICypherResultItem
表达式,但最简单的是(string identity)
。我建议你只是尝试Return("*")
?
答案 3 :(得分:0)
要重申,问题是Powershell没有内置机制来调用泛型方法,而Neo4jClient库的.Return
方法重载都是通用的。具体而言,Powershell无法提供该方法的类型。
所以有几种方法可以解决这个问题:
一个解决方案是使用反射来进行调用,但任务有点棘手。谢天谢地,这个方法已经被科技网上的一个项目所解决。见:https://gallery.technet.microsoft.com/scriptcenter/Invoke-Generic-Methods-bf7675af
在@ PetSerAl的回复中提出的第二个解决方案需要一些帮助,但在@ ChrisSkardon的帮助下,我得到了它的工作。见这里:Constructing a method call
和第三个解决方案(参见原始帖子中的更新),它依赖于创建一个c#类,其方法可以调用泛型方法
我希望在Wiki中为Neo4jClient记录这个解决方案,我希望这里记录的努力对其他人有帮助。再次感谢@PetSerAl提供所有帮助