我的初学者使用Neo4jClient时遇到的问题很遗憾:)我有一个简单的类WorkEntity,我有一个更新查询:
public class WorkEntity
{
public string Id { get; set; }
public string Description { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
var query = graphClient.Cypher
.Match("(work:Work)", "(city:City)", "(profession:Profession)", "(company:Company)", "(oldCompany:Company)", "(oldProfession:Profession)", "(oldCity:City)",
"(user:User)-[r1]->work", "work-[r2]->oldProfession", "work-[r3]->oldCompany", "work-[r4]->oldCity")
.Where((WorkEntity work) => work.Id == model.Id)
.AndWhere((CityEntity city) => city.Id == model.CityId)
.AndWhere((CityEntity oldCity) => oldCity.Id == oldModel.CityId)
.AndWhere((ProfessionEntity profession) => profession.Id == model.ProfessionId)
.AndWhere((ProfessionEntity oldProfession) => oldProfession.Id == oldModel.ProfessionId)
.AndWhere((CompanyEntity company) => company.Id == model.CompanyId)
.AndWhere((CompanyEntity oldCompany) => oldCompany.Id == oldModel.CompanyId)
.AndWhere("type(r1) = 'CURRENT'")
.AndWhere("type(r2) = 'WORK_AS_PROFESSION'")
.AndWhere("type(r3) = 'WORK_AT_COMPANY'")
.AndWhere("type(r4) = 'WORK_IN_CITY'")
.Set("work = {updatedWork}")
.WithParam("updatedWork", updatedEntity);
//If Date has been set delete current relationships
if (oldModel.EndDate == DateTime.MinValue && model.EndDate > DateTime.MinValue)
{
query = query.Delete("r1");
}
if (oldModel.ProfessionId != model.ProfessionId)
{
query = query.Delete("r2")
.CreateUnique("work-[:WORK_AS_PROFESSION]->profession");
}
if (oldModel.CompanyId != model.CompanyId)
{
query = query.Delete("r3")
.CreateUnique("work-[:WORK_AT_COMPANY]->company");
}
if (oldModel.CityId != model.CityId)
{
query = query.Delete("r4")
.CreateUnique("work-[:WORK_IN_CITY]->city");
}
query.ExecuteWithoutResults();
修改所有关系都按预期工作,但是如果例如说明从上面开始为null,则查询将不会将描述添加到现有实体(或更新任何其他属性),即使它是在updatedEntity中设置的。如果我简化查询,则添加/删除描述,并正确更新现有更改的属性。怎么可能?我真的更愿意在一次交易中完成整个查询。
var query = graphClient.Cypher
.Match("(work:Work)")
.Where((WorkEntity work) => work.Id == model.Id)
.Set("work = {updatedWork}")
.WithParam("updatedWork", updatedEntity);
答案 0 :(得分:2)
我认为,当CityId
s在我的要点中是相同的时,查询无效的原因是因为MATCH
子句:
work-[r4]-oldCity
不匹配任何内容,因此匹配失败,查询不执行任何操作。
实际上 - 如果我做对了 - 你正在尝试两个查询:
work
我认为您应该查看WITH
关键字,因为它应该有助于您的查询......
WITH
允许您将密码查询链接在一起,因此您可以将查询更改为:
var query = Client.Cypher
.Match("(work:Work)")
.Where((WorkEntity work) => work.Id == model.Id)
.Set("work = {updatedWork}")
.With("work")
.Match("(city:City)", "(profession:Profession)", "(company:Company)", "(oldCompany:Company)", "(oldProfession:Profession)", "(oldCity:City)",
"(user:User)-[r1]->work", "work-[r2]->oldProfession", "work-[r3]->oldCompany", "work-[r4]->oldCity")
.Where((WorkEntity work) => work.Id == model.Id)
.AndWhere((CityEntity city) => city.Id == model.CityId)
.AndWhere((CityEntity oldCity) => oldCity.Id == oldModel.CityId)
.AndWhere((ProfessionEntity profession) => profession.Id == model.ProfessionId)
.AndWhere((ProfessionEntity oldProfession) => oldProfession.Id == oldModel.ProfessionId)
.AndWhere((CompanyEntity company) => company.Id == model.CompanyId)
.AndWhere((CompanyEntity oldCompany) => oldCompany.Id == oldModel.CompanyId)
.AndWhere("type(r1) = 'CURRENT'")
.AndWhere("type(r2) = 'WORK_AS_PROFESSION'")
.AndWhere("type(r3) = 'WORK_AT_COMPANY'")
.AndWhere("type(r4) = 'WORK_IN_CITY'")
.WithParam("updatedWork", updatedEntity);
这将执行更新,然后执行其余操作。
可能值得一看的另一个关键字是MERGE
,但我认为WITH
可以帮助你。
答案 1 :(得分:0)
谢谢Chris,我意识到我对Neo4j的理解仍然非常有限:)上面的建议正确地更新了工作实体属性,但没有更新关系。我真的不明白为什么工作 - [r4] -oldCity关系不匹配任何东西,但无论如何我利用你关于这个的说明,经过一些试验和错误终于让查询正常工作,如:
var oldModel = GetWorkModel(model.Id);
var updatedEntity = Mapper.Map<WorkEntity>(model);
var query = graphClient.Cypher
.Match("(work:Work)", "(city:City)", "(profession:Profession)", "(company:Company)",
"(user:User)-[r1:CURRENT]->work", "work-[r2:WORK_AS_PROFESSION]->()", "work-[r3:WORK_AT_COMPANY]->()", "work-[r4:WORK_IN_CITY]->()")
.Where((WorkEntity work) => work.Id == model.Id)
.AndWhere((CityEntity city) => city.Id == model.CityId)
.AndWhere((ProfessionEntity profession) => profession.Id == model.ProfessionId)
.AndWhere((CompanyEntity company) => company.Id == model.CompanyId)
.Set("work = {updatedWork}")
.WithParam("updatedWork", updatedEntity);
if (oldModel.EndDate == DateTime.MinValue && model.EndDate > DateTime.MinValue)
query = query.Delete("r1");
if (oldModel.ProfessionId != model.ProfessionId)
query = query.Delete("r2").CreateUnique("work-[:WORK_AS_PROFESSION]->profession");
if (oldModel.CompanyId != model.CompanyId)
query = query.Delete("r3").CreateUnique("work-[:WORK_AT_COMPANY]->company");
if (oldModel.CityId != model.CityId)
query = query.Delete("r4").CreateUnique("work-[:WORK_IN_CITY]->city");
query.ExecuteWithoutResults();