【问题标题】:F# - cypher query with multiple return valuesF# - 具有多个返回值的密码查询
【发布时间】:2014-04-01 11:35:19
【问题描述】:

鉴于此查询(来自here

  let pAfollowers =
        client.Cypher
            .Match("n<-[:follows]-e")
            .Where(fun n -> n.Twitter = "tA")
            .Return<Person>("e")
            .Results
            .Select(fun x -> x.Name)

我想对其进行调整并让它返回打包在一起的多个值。 不确定该类型的外观:

let pAfollowers =
        client.Cypher
            .Match("n<-[r:follows]-e")
            .Where(fun n -> n.Twitter = "tA")
            .Return<???>("n, r, e")

其次,我想知道在CreateUnique 之后是否可以有一个返回语句。 我正在尝试调整此查询:

let knows target (details : Knows) source =
        client.Cypher
            .Match("(s:Person)", "(t:Person)")
            .Where(fun s -> s.Twitter = source.Twitter)
            .AndWhere(fun t -> t.Twitter = target.Twitter)
            .CreateUnique("s-[:knows {knowsData}]->t")
            .WithParam("knowsData", details)
            .ExecuteWithoutResults()

让它返回 stdetails

【问题讨论】:

    标签: f# neo4j neo4jclient


    【解决方案1】:

    好吧,好消息/坏消息 - 虽然在实践中好与坏:(

    先好:

    可以在 CreateUnique 之后返回,例如:

    .CreateUnique("s-[:Knows {knowsData}]-t")
    .WithParam("knowsData", details)
    .Returns<???>( "s,t" )
    .Results;
    

    坏消息:

    坏消息是您可能在 F# 中无法做到这一点。 Neo4jClient 要求您使用对象初始化器或匿名类型来转换数据,因此您可以尝试以下操作:

    type FollowingResults = { Follower : Person; Followed : Person;}
    
    let createExpression quotationExpression = LeafExpressionConverter.QuotationToLambdaExpression quotationExpression
    
    let pAfollowers =
        client.Cypher
            .Match("n<-[:follows]-e")
            .Where(fun n -> n.Twitter = "tA")
            .Return(createExpression <@ Func<ICypherResultItem, ICypherResultItem, FollowingResults>(fun (e : Cypher.ICypherResultItem) (n : Cypher.ICypherResultItem) -> {Follower = e.As<Person>(); Followed = n.As<Person>()}) @>)
            .Results
            .Select(fun x -> x)
    
    for follower in pAfollowers do
        printfn "%s followed %s" follower.Follower.Name follower.Followed.Name
    

    F# 编译器完全没有 问题。但是,Neo4jClient 将引发 Argument 异常并显示以下消息:

    表达式必须构造为对象初始值设定项(例如:n => new MyResultType { Foo = n.Bar })或匿名类型初始值设定项(例如:n => new { Foo = n.Bar } )、方法调用(例如:n => n.Count())或成员访问器(例如:n => n.As().Bar)。您不能提供代码块(例如:n => { var a = n + 1; return a; })或使用带参数的构造函数(例如:n => new Foo(n))。

    问题在于,F# 没有 有对象初始化器,也没有匿名类型,你可以为 ages 使用 F# 的东西,却一无所获,就像 C#无法识别 F# 初始化。

    【讨论】:

    • "F# 没有对象初始化器" 如果我​​理解你的意思是正确的,那么它确实有。请参阅“在初始化时为属性赋值”here
    • 不得不说我很困惑。 在 F# 3.0 中,我们添加了 CLIMutableAttribute。如果将此属性附加到 F# 记录类型 ... ,则 F# 编译器会为该类型生成的 IL 发出默认构造函数和属性设置器(尽管这些功能不会暴露给 F# 代码) @987654322 @
    • @ildjarn & NoIdeaHowToFixThis - 我的意思是就 C# 代码(在 neo4jclient 库中)而言 - 这不是对象初始化程序(我真的不是 F# 开发人员 - 非常高兴(实际上很高兴)被证明是错误的)。问题在于 C# 库如何读取代码。它在功能上是等价的,但在反射类型时相同 - 这是客户端所做的。
    • 好的,谢谢。我懂了。我找不到解决方法。这个问题对我来说是一个表演终结者。想知道我是否应该关闭这个问题并提出一个关于在类似情况下使用LeafExpressionConverter.QuotationToLambdaExpression 的更通用的问题。
    • 我不能再添加更多了 - 我已经尝试过使用结构体、F# 的初始化程序等,但我最后没有高兴 - 正如我所说 - 我不擅长 F#,所以你可以坚持看看 F# 大师是否可以提供帮助 - 但请记住 - 如果您提出在 neo4jclient 中使用它的想法的问题,您需要指定它将被 C# 库使用,这个要点:gist.github.com/cskardon/9935002 应该会有所帮助 - 如果你能得到F# 调用它并返回 true 你应该是好的。
    【解决方案2】:

    我对双方都有一些好消息。此代码将使用元组编译得很好,并且可以与支持 F# 元组的修改后的 Neo4jClient 一起使用:https://github.com/n074v41l4bl34u/Neo4jClient 解决方案基于:https://fsharppowerpack.codeplex.com/workitem/4572

      let knows target (details : Knows) source =
        client.Cypher
          .Match("(s:Person)", "(t:Person)")
          .Where(fun s -> s.Twitter = source.Twitter)
          .AndWhere(fun t -> t.Twitter = target.Twitter)
          .CreateUnique("s-[:knows {knowsData}]->t")
          .WithParam("knowsData", details)
          .Return(fun s t -> s.As<Person>(),t.As<Person>())
    
      let pAfollowers =
        client.Cypher
          .Match("n<-[:follows]-e")
          .Where(fun n -> n.Twitter = "tA")
          .Return(fun (e : Cypher.ICypherResultItem) n -> e.As<Person>().Name,n.As<Person>().Name)
    

    fun 中使用多个参数时,可以省略“(e : Cypher.ICypherResultItem)”上的类型注释。

    但是,当使用单个参数时,这摆脱了丑陋的 createExpression ) 语法。 详情请看本页底部:https://gist.github.com/cskardon/8300420

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多