这个查询:
start n = node(64) match n--x return x.Name;
应该用 C# 编写为:
var query = graphClient
.Cypher
.Start("n", node) // START n=node(123)
.Match("n--x") // MATCH n--x
.Return<string>("x.Name"); // RETURN x.Name
您提供的示例代码存在一些问题:
- 可能会有多个节点,但您的方法只返回一个
string
结果。调用Results.ToString()
将返回类似的东西"System.Collections.IEnumberable<string>"
而不是实际结果。
- 您应该避免将节点 ID 作为
long
s 传递。这样做会鼓励您使用不应该使用的原始数字。相反,使用NodeReference
. 使用 Neo4jClient 运行的任何查询都会NodeReference
返回一个对象。使用它来运行您的下一个查询。为了开始您的第一个查询,我们提供IGraphClient.RootNode
. 您基本上不需要触摸节点 ID。
- 将任何 .NET 代码包装在该部分为空的
try {} catch {}
块中始终是一个很大的禁忌。请不要在任何代码中写这个,永远。:)catch
x.Name
很可能是一个字符串,但后来你用.Return<Node<GraphNode>>
. 这基本上是说“加载x.Name
(一个字符串),但把它作为一个Node<GraphNode>
“返回给我。这没有多大意义。您需要匹配类型。
结合我上面写的查询和这些要点,你的方法应该是这样的:
public IEnumerable<string> GetAllFirstLevelRelatives(NodeReference node)
{
var query = graphClient
.Cypher
.Start("n", node) // START n=node(123)
.Match("n--x") // MATCH n--x
.Return<string>("x.name"); // RETURN x.name
return query.Results.ToList();
}
为了进一步改进这一点,您应该利用我们的类型系统。x
您的查询中的“ ”是什么?让我们想象这是一部电影。
您应该创建一个类来描述电影节点包含的内容:
public class Movie
{
public string Name { get; set; }
}
该类应该是一个“POCO”(普通的旧类对象),这意味着它应该只具有基本属性,而不是方法或逻辑。
然后,在查询中使用此类型信息:
public IEnumerable<Movie> GetAllRelatedMovies(NodeReference node)
{
var query = graphClient
.Cypher
.Start("n", node)
.Match("n--movie")
.Return<Movie>("movie");
return query.Results.ToList();
}
现在你有了一个电影列表,而不仅仅是一个字符串列表。您不太可能只想要电影的名称,因此您可以通过这种方式访问所有属性。