为 return 添加临时 属性 到 Neo4j Cypher 中的节点

Add temporary property to node in Neo4j Cypher for return

我正在使用 Neo4j .Net 客户端与 Neo4j 数据库进行交互。

我在尝试将相关节点映射到嵌套 classes 时经常遇到这个问题:

例如映射

(:Foo)-[:FOOBAR]->(:Bar)

到表格

public class Foo {
    public string FooPropOne { get; set; }
    public string FooPropTwo { get; set; }
    public List<Bar> Bars { get; set; }  
}

public class Bar {
    public string BarPropOne { get; set; }
    public string BarPropTwo { get; set; }
}

为了获得反序列化的正确输出,我必须像这样编写查询:

Foo foo = WebApiConfig.GraphClient.Cypher
    .Match("(f:Foo)-[:FOOBAR]->(b:Bar)")
    .With("@{
                FooPropOne: f.FooPropOne,
                FooPropTwo: f.FooPropTwo,
                Bars: collect(b)
             } AS Result")
    .Return<Foo>("Result")
    .SingleOrDefault();

在某种程度上这很好,并且工作得很好,但是随着 Foo class 具有的属性越多,它变得非常笨重。

我想知道我是否可以在 "With" 语句中做一些事情来在返回节点时添加一个临时的 属性(在上面的例子中 "Bars"),那确实不需要我在父节点上写每个 属性?

类似于

.With("f.Bars = collect(b)")
.Return<Foo>("f")

这实际上不会影响存储在数据库中的数据吗?

在此先感谢您的回复!

我不知道有什么方法可以像你想要的那样添加临时 属性,就个人而言 - 我会采用两种方法中的一种,而决定实际上取决于你喜欢做什么。

选项 1

选择属性版本

var foo = client.Cypher
    .Match("(f:Foo)-[:FOOBAR]->(b:Bar)")
    .With("f, collect(b) as bars")
    .Return((f, bars) => new Foo
    {
        FooPropOne = f.As<Foo>().FooPropOne,
        FooPropTwo = f.As<Foo>().FooPropTwo,
        Bars = Return.As<List<Bar>>("bars")
    }).Results.SingleOrDefault();

此版本允许您对带出的对象进行类型安全处理,在具有大量属性的 class 上确实限制了输入错误的可能性。这将使您返回Foo实例,所以不需要做任何其他处理。

选项 2

post-加工所需版本的一点点

var notQuiteFoo = client.Cypher
    .Match("(f:Foo)-[:FOOBAR]->(b:Bar)")
    .With("f, collect(b) as bars")
    .Return((f, bars) => new
    {
        Foo = f.As<Foo>(),
        Bars = bars.As<List<Bar>>()
    }).Results;

这节省了输入属性的时间,因此 class 大大节省了时间,还意味着如果您添加额外的属性,您无需记住更新查询。 但是你确实需要做一些post查询处理,比如:

IEnumerable<Foo> foos = notQuiteFoo.Results.Select(r => {r.Foo.Bars = r.Bars; return r.Foo;});

就个人而言 - 我喜欢 选项 2,因为它出现错别字的可能性较小,但我很欣赏这两者都不是您所追求的。