0

我有以下 Cypher,我正在努力将其翻译成流利的语法:

MATCH (u:User)-[:HAS_ROLE]->(r:Role)-[:ROLE_OF]->(a:App) 
RETURN u AS User, COLLECT([r, a]) AS Roles

这是我到目前为止所拥有的,但我不知道如何将 COLLECT([r, a]) 作为角色返回。我正在使用 UserDetails 类来将结果传递给视图。

var results = _graphClient.Cypher
    .Match("(user:User)-[:HAS_ROLE]->(role:Role)-[:ROLE_OF]->(app:App)")
    .Return((user,role,app) => new UserDetails {
        User = user.As<User>(),
        Roles = ???
    })
    .OrderBy("user.Username")
    .Results;

我首先尝试了一个字典,但 Neo4jClient 只允许返回 aDictionary<string, T>而我想要一个Dictionary<Role,App>.

Roles = Return.As<Dictionary<Role,App>>("COLLECT([role, app])") // doesn't work

我也考虑过创建以下类来使用,但我找不到让它工作的方法。

public class RoleWithApp
{
    public Role Role { get; set; }
    public App App { get; set; }
}

Roles = Return.As<List<RoleWithApp>>("COLLECT([role, app])") // doesn't work

我将非常感谢您对此提供一些帮助,或提出更好的方法建议。

非常感谢 :)

4

2 回答 2

1

问题在于 Neo4j 返回查询结果的方式,如果您在 Neo4j 中执行查询并为其下载 json,您最终会得到如下结果:

"[[{\"RoleName\":\"R1\"},{\"AppName\":\"A1\"}]]"

JSON.Net 无法知道如何解析它,它需要以下形式的内容:

[{"Role":{"RoleName":"Bar"},"App":{"AppName":"Foo"}}]

重要的一点是将JSON.Net 引导到正确位置"Role:"的定义。"App:"

不幸的是-即使您像@LameCoder的示例中那样直接读取值,您也无能为力-您必须对订单或返回的东西的属性进行一些欺骗性的解析。

当然,如果将来我们可以做这样的事情:COLLECT([role as Role, app as App])那么我们将处于好时光......

于 2013-11-18T12:08:36.977 回答
0

希望有人为问题所针对的特定驱动程序给出正确的答案,但是由于在评论中我被问到如何手动完成并且没有足够的空间将其放在评论中,所以我已经将其作为答案。

这是非常基本的,应该可以帮助您开始尝试手动执行此操作。

var to = "http://localhost:7474/db/data/cypher";
var reqMsg = new HttpRequestMessage("POST", to);
var cypher = @" ... ";
var parameters = new Dictionary<string, object>();

var req = new {
    query = cypher,
    @params = parameters //Use @ to be able to use a keyword as an identifier
};

var body = JToken.FromObject(req);

//You don't have to use streams if you don't want to. I just like to avoid creating large strings
reqMsg.Content = new PushStreamContent((stream, content, context) =>
                    {
                        using (var sw = new StreamWriter(stream))
                        using (var jw = new JsonTextWriter(sw))
                        {
                            body.WriteTo(jw);
                        }
                    }, "application/json");

using (var client = new HttpClient())
{
    var response = await client.SendAsync(reqMsg, HttpCompletionOption.ResponseHeadersRead);
    if (!response.IsSuccessStatusCode)
    {
        var s = await response.Content.ReadAsStringAsync();
        throw new Exception("Got status code " + response.StatusCode + " with error: " + s);
    }

    using (var reader = new JsonTextReader(new StreamReader(await response.Content.ReadAsStreamAsync())))
    {
        var o = JObject.Load(reader);
        return o;
    }

}
于 2013-11-14T16:32:19.767 回答