如何使用Neo4jClient返回COLLECT([role,app])?

时间:2013-11-11 10:01:47

标签: asp.net-mvc neo4j cypher neo4jclient

我有以下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类来启用将结果传递给View。

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只允许以Dictionary<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

我非常感谢对此提供的一些帮助,或者建议采用更好的方法。

非常感谢:)

2 个答案:

答案 0 :(得分:1)

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

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

JSON.Net无法知道如何解析它,它需要表单中的内容:

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

重要的是"Role:""App:"定义,它们将JSON.Net指引到正确的位置。

不幸的是 - 你可以做很多事情,即使你直接读取@LameCoder的例子中的值 - 你将不得不做一些与订单相关的解析,或者你的事情上的属性回来。

当然,如果将来我们可以做类似的事情:COLLECT([role as Role, app as App])那么我们将会过得很愉快......

答案 1 :(得分: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;
    }

}