f# neo4j neo4jclient

F#- consulta de cifrado con valores de retorno mĂșltiples



neo4j neo4jclient (2)

OK, buenas / malas noticias, aunque en la práctica el bien se atenúa con mal :(

Bien primero:

Puedes regresar después de CreateUnique, algo así como:

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

Malas noticias:

La mala noticia es que probablemente no puedas hacerlo en F #. Neo4jClient requiere que use ya sea inicializadores de objetos o tipos anónimos para transmitir los datos, por lo que podría intentar algo como:

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

Para lo cual el compilador F # no tendrá ningún problema. Sin embargo, Neo4jClient lanzará una excepción Argument con el siguiente mensaje:

La expresión debe construirse como un inicializador de objetos (por ejemplo: n => new MyResultType {Foo = n.Bar}), un inicializador de tipo anónimo (por ejemplo: n => new {Foo = n.Bar}), un llamada de método (por ejemplo: n => n.Count ()), o un descriptor de acceso de miembro (por ejemplo: n => n.As (). Bar). No puede suministrar bloques de código (por ejemplo: n => {var a = n + 1; return a;}) o usar constructores con argumentos (por ejemplo: n => new Foo (n)).

El problema es que F # no tiene inicializadores de objetos, ni tipos anónimos, puede discutir con las cosas F # por edades y no llegar a ningún lado, ya que C # no reconoce la inicialización F #.

Dada esta consulta (de aquí )

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

Me gustaría ajustarlo y hacer que devuelva múltiples valores empaquetados juntos. No estoy seguro de cómo debería verse el tipo:

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

En segundo lugar, me preguntaba si es posible tener una declaración de devolución después de CreateUnique . Estoy tratando de modificar esta consulta:

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()

para que devuelva s , t y los details .


Tengo buenas noticias para ambos. Este código se compilará perfectamente utilizando tuplas y se puede usar con un Neo4jClient modificado que admita F # Tuples: https://github.com/n074v41l4bl34u/Neo4jClient Solution se basa en: 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)

La anotación de tipo en ''(e: Cypher.ICypherResultItem)'' se puede omitir cuando se usan más de un argumento de manera divertida .

Sin embargo, al usar un solo argumento, esto elimina la fea sintaxis createExpression <@ Func (...) @>) . Para detalles sobre por qué mirar en la parte inferior de esta página: https://gist.github.com/cskardon/8300420