Question

I need to update all the properties of a given node, using mutating cypher. I want to move away from Node and NodeReference because I understand they are deprecated, so can't use IGraphClient.Update. I'm very new to mutating cypher. I'm writing in C#, using Neo4jclient as the interface to Neo4j.

I did the following code which updates the "Name" property of a "resunit" where property "UniqueId" equals 2. This works fine. However,
* my resunit object has many properties
* I don't know which properties have changed
* I'm trying to write code that will work with different types of objects (with different properties)

It was possible with IGraphClient.Update to pass in an entire object and it would take care of creating cypher that sets all properies.

Can I somehow pass in my object with mutating cypher as well? The only alternative I can see is to reflect over the object to find all properties and generate .Set for each, which I'd like to avoid. Please tell me if I'm on the wrong track here.

        string newName = "A welcoming home";

        var query2 = agencyDataAccessor
                    .GetAgencyByKey(requestingUser.AgencyKey)
                    .Match("(agency)-[:HAS_RESUNIT_NODE]->(categoryResUnitNode)-[:THE_UNIT_NODE]->(resunit)")
                    .Where("resunit.UniqueId = {uniqueId}")
                    .WithParams(new { uniqueId = 2 })
                    .With("resunit")
                    .Set("resunit.Name = {residentialUnitName}")
                    .WithParams(new { residentialUnitName = newName });

        query2.ExecuteWithoutResults();
Was it helpful?

Solution

It is indeed possible to pass an entire object! Below I have an object called Thing defined as such:

public class Thing
{
    public int Id { get; set; }
    public string Value { get; set; }
    public DateTimeOffset Date { get; set; }
    public int AnInt { get; set; }
}

Then the following code creates a new Thing and inserts it into the DB, then get's it back and updates it just by using one Set command:

Thing thing = new Thing{AnInt = 12, Date = new DateTimeOffset(DateTime.Now), Value = "Foo", Id = 1};

gc.Cypher
    .Create("(n:Test {thingParam})")
    .WithParam("thingParam", thing)
    .ExecuteWithoutResults();

var thingRes = gc.Cypher.Match("(n:Test)").Where((Thing n) => n.Id == 1).Return(n => n.As<Thing>()).Results.Single();
Console.WriteLine("Found: {0},{1},{2},{3}", thingRes.Id, thingRes.Value, thingRes.AnInt, thingRes.Date);

thingRes.AnInt += 100;
thingRes.Value = "Bar";
thingRes.Date = thingRes.Date.AddMonths(1);

gc.Cypher
    .Match("(n:Test)")
    .Where((Thing n) => n.Id == 1)
    .Set("n = {thingParam}")
    .WithParam("thingParam", thingRes)
    .ExecuteWithoutResults();

var thingRes2 = gc.Cypher.Match("(n:Test)").Where((Thing n) => n.Id == 1).Return(n => n.As<Thing>()).Results.Single();
Console.WriteLine("Found: {0},{1},{2},{3}", thingRes2.Id, thingRes2.Value, thingRes2.AnInt, thingRes2.Date);

Which gives:

Found: 1,Foo,12,2014-03-27 15:37:49 +00:00
Found: 1,Bar,112,2014-04-27 15:37:49 +00:00

All properties nicely updated!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top