2016-09-15 3 views
0

Я пытаюсь написать запрос в neo4jclient, чтобы добавить/обновить все части дерева иерархии в базе данных в 1 хит. У меня возникли проблемы, когда дело доходит до использования слияния с коллекциями. Я вижу функцию foreach, но не успел ее заставить работать.Neo4jClient ForEach merge

До сих пор я пробовал ниже Я пробовал писать его как полную строку, но все равно получаю исключение из «Neo4jClient.NeoException: SyntaxException: Invalid input».: Ожидается символ идентификатора, пробел, } 'или': '(строка 6, столбец 90 (смещение: 266))'

Ниже строки показано, как я могу представить код для работы, если функция foreach работает как C#, но не знает правильного синтаксиса.

Любая помощь была бы действительно оценена.

public void Save(CypherAspirationsViewModel aspirations, string emailAddress) 
    { 
     var query = graphClient.Cypher 
      .Match("(user:User)") 
      .Where((CypherUser user) => user.EmailAddress == emailAddress) 

      // Aspirations 
      .Merge("user" + CypherRelationships.Aspirations + ">(aspirations:Aspirations {Guid: {aspirationsGuid}})") 
      .OnCreate() 
      .Set("aspirations = {aspirations}") 
      .WithParams(new 
      { 
       aspirationsGuid = aspirations.CypherAspirations.Guid, 
       aspirations = aspirations.CypherAspirations 
      }); 


     // Permanent Remuneration 
     if (aspirations.CypherPermanentRemuneration != null) { 
      query = query.Merge("aspirations" + CypherRelationships.PermanentRemuneration + ">(permanentRemuneration:Remuneration {Guid: {permanentRemunerationGuid}})") 
       .OnCreate() 
       .Set("permanentRemuneration = {permanentRemuneration}") 
       .WithParams(new 
       { 
        permanentRemunerationGuid = aspirations.CypherPermanentRemuneration.Guid, 
        permanentRemuneration = aspirations.CypherPermanentRemuneration 
       }); 
      } 

     // Contract Remuneration 
     if (aspirations.CypherContractRemuneration != null) { 
      query = query.Merge("aspirations" + CypherRelationships.ContractRemuneration + ">(contractRemuneration:Remuneration {Guid: {contractRemunerationGuid}})") 
       .OnCreate() 
       .Set("contractRemuneration = {contractRemuneration}") 
       .WithParams(new 
       { 
        contractRemunerationGuid = aspirations.CypherContractRemuneration.Guid, 
        contractRemuneration = aspirations.CypherContractRemuneration 
       }); 
      } 

     // Consultant Remuneration 
     if(aspirations.CypherConsultantRemuneration != null) 
     { 
      query = query.Merge("aspirations" + CypherRelationships.ConsultantRemuneration + ">(consultantRemuneration:Remuneration {Guid: {consultantRemunerationGuid}})") 
       .OnCreate() 
       .Set("consultantRemuneration = {consultantRemuneration}") 
       .WithParams(new 
       { 
        consultantRemunerationGuid = aspirations.CypherConsultantRemuneration.Guid, 
        consultantRemuneration = aspirations.CypherConsultantRemuneration 
       }); 
     } 

     // Locations 
     if (aspirations.CypherLocations != null) 
     { 
      //string forEachString = "(n in {locations} | merge (aspirations " + CypherRelationships.Location + ">(location:Location {Guid: {n.Guid}})) on create set location.Name = n.Name, location.Longitude = n.Longitude, location.Latitude = n.Latitude)"; 
      //query = query 
      // .ForEach(forEachString) 
      // .WithParam("locations", aspirations.CypherLocations); 

      query = query.ForEach("CypherLocation location in aspirations.CypherLocations") 
       .Merge("aspirations" + CypherRelationships.Location + ">(location:Location {Guid: {locationGuid}})") 
       .OnCreate() 
       .Set("location = {location}") 
       .WithParams(new 
       { 
        locationGuid = location.Guid, 
        location = location 
       }); 
     } 

     query.ExecuteWithoutResults(); 
    } 

Cypher Запрос:

MATCH (user:User) 
WHERE (user.EmailAddress = "email") 
MERGE user-[:ASPIRATIONS]->(aspirations:Aspirations {Guid: "0d700793-4702-41ee-99f1-685472e65e51"}) 
ON CREATE 
SET aspirations = { 
    "FullTime": true, 
    "PartTime": false, 
    "Permanent": false, 
    "Contract": false, 
    "Consultant": false, 
    "WillingToRelocate": false, 
    "CommuteEnum": 40, 
    "Guid": "0d700793-4702-41ee-99f1-685472e65e51" 
} 


FOREACH (n in [ 
    { 
    "Name": "Location1", 
    "Longitude": 10.0, 
    "Latitude": 1.0, 
    "Guid": "a9f25fda-9559-4723-80ec-d8711a260adc" 
    } 
] | 
merge (aspirations -[:LOCATION]->(location:Location {Guid: {n.Guid}})) 
on create set location.Name = n.Name, location.Longitude = n.Longitude, location.Latitude = n.Latitude) 
+0

Привет, Гэвин, если вы поставили точку останова на строку 'query.ExecuteWithoutResults', вы могли бы получить значение' query.Query.DebugQueryText', так как это поможет решить, в чем проблема! –

+0

Спасибо Крис, я добавил debugquerytext. –

+0

Извините за задержку - если вы выполните Cypher в окне управления (http: // localhost: 7474 /), вы получите ту же ошибку (вам нужно будет найти/заменить «\» и «\ r \ n', чтобы заставить его работать) –

ответ

0

Хорошо, я думаю, что я получил его прибили. Есть несколько Cypher необходимые изменения (в зависимости от версии сервера)

Во-первых, исходная ошибка из в ForEach финале Merge - у вас есть {Guid: {n.Guid}}, но вам не нужны дополнительные {} - так и должно быть: {Guid: n.Guid}.

После того, как вы получили, что, если вы собираетесь против 3,0 DB, вам необходимо добавить некоторые скобки в своих методах слияния, например:

.Merge("user" + CypherRelationships.Aspirations + ">(aspirations:Aspirations {Guid: {aspirationsGuid}})") 

должны стать:

.Merge("user" + CypherRelationships.AspirationsWithClosingParentheses + ">(aspirations:Aspirations {Guid: {aspirationsGuid}})") 

AspirationsWithClosingParentheses, где что-то вроде:

var AspirationsWithClosingParentheses = "Aspirations)--" 

Вам нужно сделать это для каждый слияние, поскольку 3.0 требует, чтобы идентификаторы были окружены!