私はNeo4jを初めて使うC#開発者です。私はグラフのコンセプトを学び、Cypherを試して2、3週間過ごしました。それはこれまでのところ良い経験です!Neo4j.DriverでNeo4jとの関係を追加する
公式のC#ドライバを使用してコードからの実際のデータで作業しようとしました。私はドライバが実際の.Net機能を一切持っていないAPIのラッパーにすぎないことに驚きました。
私はこのパターンとサイファー文を作成するために、細かな管理対象ノードの作成:
CREATE (:Movie {tmdbId: {tmdbId}, imdbId: {imdbId}, title: {title}, originalTitle: {originalTitle}, collectionInfo: {collectionInfo}, genres: {genres}, releaseDate: {releaseDate}, plot: {plot}, tagline: {tagline}, originalLanguage: {originalLanguage}, tmdbPopularity: {tmdbPopularity}, tmdbVoteAverage: {tmdbVoteAverage}, tmdbVoteCount: {tmdbVoteCount}, budget: {budget}})
パラメータコレクションは自動的にオブジェクトから生成されます。それはうまく動作します。しかし、リレーションシップを作成すると予期しないエラーが発生します。
これは私がリレーションシップを作成するために使用するステートメントです。ソースノードとターゲットノードはIdで検索されます。
MATCH (s:Person), (t:Movie) WHERE s.personId=35742 AND t.movieId=19404 CREATE (s)-[r:ACTED_IN {order: {order}, character: {character}}]->(t) RETURN r
私が受け取るエラーは、次のとおりです。
System.Reflection.TargetParameterCountException: 'Parameter count mismatch.'
パラメータコレクションは、前回と同じように作成されます。これは、 "order"と "character"という2つのプロパティを期待通りに保持します。
私が紛失しているという記述に何らかのエラーがありますか?
/// <summary>
/// Add object as node in Neo4j database.
/// All public properties will automatically be added as properties of the node.
/// </summary>
/// <param name="obj">Generic POCO object</param>
/// <param name="label">Specify type name to be uses. Skip if you are satisfied with object type name.</param>
public void AddNode(object obj, string label = null)
{
using (var session = _driver.Session())
{
label = label ?? obj.GetType().Name;
var parameters = GetProperties(obj);
var valuePairs = string.Join(", ", parameters.Select(p => $"{p.Key}: {{{p.Key}}}"));
var statement = $"CREATE (:{label} {{{valuePairs}}})";
var result = session.Run(statement, parameters);
Debug.WriteLine($"{result.Summary.Counters.NodesCreated} {label} node created with {result.Summary.Counters.PropertiesSet} properties");
}
}
public void AddRelation(string sourceNodeName, string sourceIdName, string targetNodeName, string targetIdName, string relationName, object relation, string relationSourceIdName, string relationPropertyIdName)
{
using (var session = _driver.Session())
{
//MATCH(s:Person), (t:Person)
//WHERE s.name = 'Source Node' AND t.name = 'Target Node'
//CREATE(s) -[r:RELTYPE]->(t)
//RETURN r
var parameters = GetProperties(relation);
var sourceId = parameters[relationSourceIdName];
var targetId = parameters[relationPropertyIdName];
var properties = parameters.Where(p => p.Key != relationSourceIdName && p.Key != relationPropertyIdName).ToList();
var valuePairs = string.Join(", ", properties.Select(p => $"{p.Key}: {{{p.Key}}}"));
var statement = $"MATCH (s:{sourceNodeName}), (t:{targetNodeName}) WHERE s.{sourceIdName}={sourceId} AND t.{targetIdName}={targetId} CREATE (s)-[r:{relationName} {{{valuePairs}}}]->(t) RETURN r";
var result = session.Run(statement, properties);
Debug.WriteLine($"{result.Summary.Counters.RelationshipsCreated} {relationName} relations created with {result.Summary.Counters.PropertiesSet} properties");
}
}
private static Dictionary<string, object> GetProperties(object obj)
{
var dictionary = new Dictionary<string, object>();
foreach (var property in obj.GetType().GetProperties())
{
var propertyName = property.Name;
var value = property.GetValue(obj);
var array = value as string[];
if (array != null)
{
value = string.Join(",", array);
}
if (value is DateTime)
{
var dateTime = (DateTime)value;
value = dateTime.ToString("yyyy-MM-dd");
}
dictionary.Add(propertyName.ToCamelCase(), value);
}
return dictionary;
}
こんにちはヤコブ!私はNeo4jブラウザにあなたの質問をコピーし、貼り付けて実行し、うまくいった!だからあなたの質問はあなたのC#コードに関係していると思いますよね?私たちとクエリを生成するC#コードを共有できますか?また、[Neo4jClientライブラリ](https://github.com/Readify/Neo4jClient)を使用していますか? –
速い応答のために@BrunoPeresに感謝します!あなたは正しいです、ステートメントはNeo4jブラウザで正常に動作するので、C#ラッパーに関係していると思います。あなたのレビューのために上記の方法を追加しました。私はこの問題が、角括弧の中の中括弧に関係していると考えているので、Runメソッドが文とパラメータを解析するのは難しいですか? –
'Debug.WriteLine(statement);'の出力は何ですか? –