我有以下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
我非常感谢对此提供的一些帮助,或者建议采用更好的方法。
非常感谢:)
答案 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;
}
}