powershell - 返回重载失败

标签 powershell neo4j neo4jclient

我正在关注这篇小文章: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 中将是一个代码块,但是,我收到以下错误:

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



我哪里错了?

* 更新我 *

通过下面@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; }
}

我的类(class)有点不同
Add-Type -TypeDefinition "public class Project { public string Code; public string Name; public string Parent; public string Lifespan; }"

他们的密码
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)

但我得到一个错误

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



这一次,实际上是非常清楚和可以理解的。所以我想要的是一个方法调用,例如n => n.Count()显然没有做到这一点。

帮助?

* 更新二 *

所以,继续从 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()

这产生了一个启发性的错误:

Exception calling "get_Results" with "0" argument(s): "The graph client is not connected to the server. Call the Connect method first."



所以这清楚地表明我首先需要做的是:
$neo.Connect()

另外,我需要在查询的 match 子句周围加上括号:
$neo.Cypher.Match("(n:Project)").Return([NeoExp]::GetProject)

现在我得到了 .Results 中预期的 27 个结果。字段...但是,结果都是空白的。所以我认为这可能与 n.As<Project>() 有关也许我的类(class)没有正确定义并且失败了。有什么想法吗?

* 更新 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:我欠你一杯啤酒

最佳答案

Return 有两个问题方法:

  • 它接受表达式树类型的参数,而不是编译的委托(delegate)类型。并且 PowerShell 没有一种简单的方法可以从 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
    

    关于powershell - 返回重载失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30314696/

    相关文章:

    java - 遍历图形时无法删除节点 - neo4j java 嵌入式 api

    neo4j - 如何在使用 cypher 与 UNWIND 迭代时删除关系

    C# Neo4jClient TaskCancelled 异常

    node.js - 将TFS2017任务更新到最新版本

    powershell - 通过模块访问哈希表

    powershell - New-AzureRmResourceGroup 命令在 powershell 中不起作用

    windows - 用于更改服务帐户的 Powershell 脚本

    neo4j - 如何删除neo4j中的标签?

    json - 用Neo4J创建家谱

    c# - 将返回值组合成单一类型