Search code examples
c#neo4jneo4jclient

Neo4jClient - How to get node?


I'm trying out the Neo4jClient for Neo4j graph database, using the examples found here.

In the following fairly simple code:

var client = new GraphClient(new Uri("http://localhost:7474/db/data"));
client.Connect();

var myNodeReference = client.Create(new MyNode { Foo = "bar" });
var myNode = client.Get<MyNode>(myNodeReference);

On the last line (.Get) the following error is thrown:

An item with the same key has already been added.

(the same error is thrown even if the Get is the first and only method, and I'm getting the node by using some existing key created previously).

After looking at the stack trace I found that it's related to Neo4jClient, rather than Neo4j db, because as it seems it's an error thrown when adding to Dictionary:

 at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at Neo4jClient.Deserializer.CommonDeserializerMethods.GetPropertiesForType(Type objType) in c:\TeamCity\buildAgent\work\460e89b30f53245b\Neo4jClient\Deserializer\CommonDeserializerMethods.cs:line 344
   at Neo4jClient.Deserializer.CommonDeserializerMethods.Map(Object targetObject, JToken parentJsonToken, CultureInfo culture, IEnumerable`1 typeMappings, Int32 nestingLevel) in c:\TeamCity\buildAgent\work\460e89b30f53245b\Neo4jClient\Deserializer\CommonDeserializerMethods.cs:line 228
   at Neo4jClient.Deserializer.CommonDeserializerMethods.CreateAndMap(Type type, JToken element, CultureInfo culture, IEnumerable`1 typeMappings, Int32 nestingLevel) in c:\TeamCity\buildAgent\work\460e89b30f53245b\Neo4jClient\Deserializer\CommonDeserializerMethods.cs:line 210
   at Neo4jClient.Deserializer.CommonDeserializerMethods.SetPropertyValue(Object targetObject, PropertyInfo propertyInfo, JToken value, CultureInfo culture, IEnumerable`1 typeMappings, Int32 nestingLevel) in c:\TeamCity\buildAgent\work\460e89b30f53245b\Neo4jClient\Deserializer\CommonDeserializerMethods.cs:line 132
   at Neo4jClient.Deserializer.CommonDeserializerMethods.Map(Object targetObject, JToken parentJsonToken, CultureInfo culture, IEnumerable`1 typeMappings, Int32 nestingLevel) in c:\TeamCity\buildAgent\work\460e89b30f53245b\Neo4jClient\Deserializer\CommonDeserializerMethods.cs:line 234
   at Neo4jClient.Deserializer.CustomJsonDeserializer.Deserialize[T](RestResponse response) in c:\TeamCity\buildAgent\work\460e89b30f53245b\Neo4jClient\Deserializer\CustomJsonDeserializer.cs:line 59
   at RestSharp.RestClient.Deserialize[T](IRestRequest request, RestResponse raw)

If relevant, these are the package versions from NuGet:
<package id="Neo4jClient" version="1.0.0.397" targetFramework="net40-Client" />
<package id="Newtonsoft.Json" version="4.0.8" targetFramework="net40-Client" />
<package id="RestSharp" version="102.7" targetFramework="net40-Client" />

What am I doing wrong here?

Edit MyNode class:

[JsonObject]
public class MyNode
{
    [JsonProperty("Bar")]
    public string Foo { get; set; }

    [JsonIgnore]
    public string Bar { get; set; }
}

Solution

  • Unless you really need to do it, I would take off the [JsonProperty("Bar")] bit, as that is what is causing the trouble. The deserialiser can't distinguish between the actual property 'Bar', and the JsonProperty 'Bar'

    If you take it off, your code will work fine.

    If you want to use the Json stuff, you could create another Node object:

    public class OtherNode { public string Bar { get;set;} }
    

    and deserialise into that:

    var nodeReference = client.Create(new MyNode { Foo = "blah" });
    var retrieved = client.Get<OtherNode>(nodereference);
    

    and that will work.