将Neo4j节点的<id>放入类中

问题描述

我的班级定义:

public class User{
    public int Id {get;set;}
    public string Name {get;set;}
}

我的密码:

MATCH (u:User)
WHERE id(u) = 15
RETURN u{.*,id:id(u)} as user

我的C#.Net代码

var users = await graphClient.Cypher.Match("(u:User)").Where("id(u)=15).Return<User>(u => u.As<User>()).ResultAsync;

当我检查结果时,User.Id始终为NULL。

注意:我尚未在节点内创建和Id属性,但我想使用Neo4j的内置ID。

see attached

解决方法

您在浏览器中看到的<id>是基础的Neo4j ID,Id类的User属性试图获取的不是Node的普通属性。

要获得所需的功能,您必须对代码做更多的事情,实际上,您在Cypher中所拥有的几乎全部。

var users = await graphClient.Cypher
    .Match("(u:User)")
    .Where("id(u)=15")
    .With("u{.*,Id:id(u)} AS user")
    .Return(user => user.As<User>())
    .ResultsAsync;

我将转换成With的类型,这主要是因为我可以使用.*表示法,并且还允许我返回user.As<User>()

我还将您从Id返回的id:id(u)属性的大小写更改为Id:id(u)-因为您的班级是大写。

我也建议您为ID使用一个参数:

var users = await graphClient.Cypher
    .Match("(u:User)")
    .Where("id(u)=$id")
    .With("u{.*,Id:id(u)} AS user")
    .WithParam("id",15)
    .Return(user => user.As<User>())
    .ResultsAsync;

这将使Neo4j的查询分析器认识到这是同一查询多次运行,从而使查询速度更快。

现在-在此情况下,除非极少数情况,否则您实际上不应该将<id>用作可查询参数。 <id>可以在数据库时间内指向不同的事物。例如,如果您删除了该用户并添加了另一个用户,则该新用户可能会重用<id>。如果可以的话,请始终尝试在.NET中找到另一个唯一的ID来使用,Guid.NewGuid()是经典之一,或者,当然,对于用户而言-电子邮件地址通常是不错的选择。