从 C# 中的 Cypher 结果反序列化为嵌套对象

Deserialize into nested objects from Cypher Result in c#

我一直想通过 neo4jclient 将 Cypher 结果自动反序列化为相应的对象。

这些是 类 我想让它反序列化成

public class QuestionHub
{
    public string Id { get; set; }
    public string Title { get; set; }
    public ICollection<Question> Questions {get;set;}
}

public class Question
{
    public string Id { get; set; }
    public string Title { get; set; }
    public ICollection<Answer> Answers { get;set; }
}

public class Answer
{
    public string Id { get; set; }
    public string Value { get; set; }
}

我知道这个代码会将相应的 QuestionHub 放入一个 QuestionHub 列表中。这正是我想要的,但问题是那些导航到其他 类 的 属性 不包括在内。

var hubQuery = graphClient.Cypher
        .Match("(qh:QuestionHub)-[:PART_OF]-(q:Question)-[:ANSWER]-(a:Answer)")
        .ReturnDistinct<QuestionHub>("qh");

这是 result 如您所见,问题不包括在内。

每当我这样做时

var hubQuery = graphClient.Cypher
        .Match("(qh:QuestionHub)-[:PART_OF]-(q:Question)-[:ANSWER]-(a:Answer)")
        .ReturnDistinct<QuestionHub>("*");

我收到错误

System.ArgumentException: 'Neo4j returned a valid response, however Neo4jClient was unable to deserialize into the object structure you supplied.
    
    First, try and review the exception below to work out what broke.
    
    If it's not obvious, you can ask for help at http://whosebug.com/questions/tagged/neo4jclient
    
    Include the full text of this exception, including this message, the stack trace, and all of the inner exception details.
    
    Include the full type definition of Neo4JTests.QuestionHub.
    
    Include this raw JSON, with any sensitive values replaced with non-sensitive equivalents:
    
    { "columns":["a","q","qh"], "data":[[ {"data":{ "Value":"answer9aaf5134-9e73-4681-ba2f-e8224242ff19","Id":"9aaf5134-9e73-4681-ba2f-e8224242ff19" }},{"data":{ "Title":"questiond287a365-364a-4de0-b9f2-574893c1eaaa","Id":"d287a365-364a-4de0-b9f2-574893c1eaaa" }},{"data":{ "Title":"questionHub222a2fbe-6644-491a-b0a1-66df59f05f11","Id":"222a2fbe-6644-491a-b0a1-66df59f05f11" }} ]] } Arg_ParamName_Nam'
Inner Exception
InvalidOperationException: The deserializer is running in single column mode, but the response included multiple columns which indicates a projection instead. If using the fluent Cypher interface, use the overload of Return that takes a lambda or object instead of single string. (The overload with a single string is for an identity, not raw query text: we can't map the columns back out if you just supply raw query text.)

这个错误可能是因为密码结果给出了多列而不是一列。

This就是我想要得到的

如果我这样做

var hubQuery = graphClient.Cypher
                .Match("(u:User)-[:CREATOR_HUB]-(qh:QuestionHub)-[:PART_OF]-(q:Question)-[:ANSWER]-(a:Answer)")
                .With("u, qh, q, COLLECT({Id: a.Id, Value: a.Value}) as answers")
                .With("u, qh, COLLECT({Id: q.Id, Title: q.Title, Answers:answers}) as questions")
                .With("{Creator: {Id:u.Id, FirstName: u.FirstName, LastName: u.LastName}," +
                      "Id: qh.Id, Title: qh.Title, Questions: questions} as result")
                .ReturnDistinct<string>("result");

var hubQueryRes = await hubQuery .ResultsAsync;

            List<QuestionHub> hubList = new List<QuestionHub>();
            foreach (var hub in hubQueryRes )
            {
                hubList .Add(JsonConvert.DeserializeObject<QuestionHub>(hub));
            }

我得到了我想要的,但我需要写所有这些 .With 我想要一种无需所有 .With 写入即可自动执行此操作的方法。

我正在寻找一种方法来自动将 Cypher 结果反序列化为包含嵌套对象的相应对象。

有办法吗?

提前致谢!

你 100% 正确,它没有创建你的 QuestionHub 实例的原因是因为 return 的格式完全错误,客户端无法处理。

不幸的是 - 您的 with 解决方法是唯一的方法 - 当您使用它 return Cypher 的输出为 Json 解串器可以处理的格式时。

我能看到的最好的做法是:

var query = gc.Cypher
    .Match("(qh:QuestionHub)-[:PART_OF]-(q:Question)-[:ANSWER]-(a:Answer)")
    .With("qh, q{.*, Answers: COLLECT(a)} AS qAndA")
    .With("qh{.*, Questions: COLLECT(qAndA)} AS result")
    .Return(result => result.As<QuestionHub>());

请记住,您还需要 ICollectionListIEnumerable 才能正确反序列化 - 不支持反序列化为 ICollection