1

I'm having trouble retrieving matched relationships from a Cypher query.

I have this simple trial code:

var movie = client.Create(new Movie { Title = "The Matrix" });

client.Create(new Actor { Name = "Keanu Reeves" },
    new ActedIn(movie, new ActedInPayload { Role = "Neo" }));

client.Create(new Actor { Name = "Hugo Weaving" },
    new ActedIn(movie, new ActedInPayload { Role = "Agent Smith" }));

var actorsAndRoles = client
    .Cypher
    .Start(new { movie = movie })
    .Match("actor-[r:ACTED_IN]->movie")
    .Return((actor, r) => new
    {
        Actor = actor.As<Node<Actor>>()
        // ActedIn = r.As<?????>()
    })
    .Results;

Problem is that I can't work out how to cast the r (with the matched relationship).

Tried various ".As" type casts, but none work. Casting to Relationship doesn't work because my relationship class doesn't have a parameterless constructor - but then the Relationship base class doesn't have a parameterless constructor itself, so don't think that would work. Casting to RelationshipReference on the other hand causes an exception. Not casting at all (just returning r) causes a "not supported" exception.

There are some related SO entries about this issue, but the suggested code there either no longer works or is deprecated.

How do I retrieve the matched relationship?

4

1 回答 1

5

您可以为您的关系类型创建一个无参数构造函数,您只需将“duff”数据传递给它,我知道这听起来很糟糕,但由于您并不真正需要它,它不会伤害您:

public class ActedIn : Relationship<ActedInPayload>, IRelationshipAllowingSourceNode<Actor>, IRelationshipAllowingTargetNode<Movie>
{
    public ActedIn() : base(-1, null) {}
    public ActedIn(NodeReference targetNode, ActedInPayload data) : base(targetNode, data) {}

    public override string RelationshipTypeKey
    {
        get { return "ACTED_IN"; }
    }
}

这就是ActedIn类,无参数构造函数将“-1”链接到基本构造函数。

然后您的查询变为:

var actorsAndRoles = client
    .Cypher
    .Start(new {movie})
    .Match("actor-[r:ACTED_IN]->movie")
    .Return((actor, r) => new
        {
            Actor = actor.As<Node<Actor>>(),
            ActedIn = r.As<RelationshipInstance<ActedInPayload>>()
        })
    .Results;

请注意,它被转换为notRelationshipInstance类型,然后,以获取您可能想要的数据:ActedInPayload ActedIn

foreach (var actorsAndRole in actorsAndRoles)
{
    Console.WriteLine("{0} acted as {1} - which is in the db as {2}-[ACTED_IN]->{3}", 
        actorsAndRole.Actor.Data.Name, 
        actorsAndRole.ActedIn.Data.Role, 
        actorsAndRole.ActedIn.StartNodeReference.Id, 
        actorsAndRole.ActedIn.EndNodeReference.Id);
}

这会给你类似的东西:

基努·里维斯(Keanu Reeves)扮演 Neo - 在数据库中为 482-[ACTED_IN]->481

Hugo Weaving 担任特工 Smith - 在数据库中为 483-[ACTED_IN]->481

虽然显然在您自己的数据库上有不同的数字。

于 2013-07-11T16:18:20.890 回答