ArangoDb.Net upsert 总是插入
ArangoDb.Net upsert always insert
我正在使用 ArangoDatabase 及其驱动程序制作一个带有 CRUD 功能的小型应用程序:
这是我的代码:
var insert = new Account
{
Email = "email01@gmail.com",
FirstName = "Adam",
LastName = "Smith"
};
var update = new Account
{
Email = "email01@gmail.com",
FirstName = "John",
LastName = "Peterson"
};
using (var arangoDatabase = new ArangoDatabase(new DatabaseSharedSetting()
{
Url = "http://127.0.0.1:8529/",
Database = "_system",
Credential = new NetworkCredential()
{
UserName = "root",
Password = "xvxvc"
}
}))
{
arangoDatabase.Query()
.Upsert(_ => new Account() {Email = insert.Email},
_ => insert, ((aql, x) => update))
.In<Account>()
.Execute();
}
第一次 运行,[插入] 对象被添加到数据库中。
因此,我现在的数据库是:
但是在第二次 运行 代码时,它抛出了一个错误:
unique constraint violated (while executing). ErrorNumber: 1210 HttpStatusCode: 409
问题是:我的问题是什么,如何解决?
谢谢,
问题可能是 upsert 搜索表达式序列化:
假设 Account
class 定义为:
public class Account
{
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
upsert 搜索表达式:new Account() {Email = insert.Email}
将序列化为:
{ Email: "email01@gmail.com", FirstName: null, LastName: null }
但预期的是:
{ Email: "email01@gmail.com" }
由于搜索表达式永远找不到文档,因此会发生插入,您会得到 unique constraint violated
.
有两种解决方案可以避免序列化 FirstName
和 LastName
成员:
一个是我们可以使用 Json.net JsonProperty
属性来忽略序列化中的空值:
public class Account
{
public string Email { get; set; }
[Newtonsoft.Json.JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string FirstName { get; set; }
[Newtonsoft.Json.JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string LastName { get; set; }
}
另一种方式是使用匿名对象进行搜索表达式:
arangoDatabase.Query()
.Upsert(_ => new Account() {Email = insert.Email}
// should be
arangoDatabase.Query()
.Upsert(_ => new {Email = insert.Email}
关于使用匿名对象的一个注意事项是 Email
成员可以根据您为其命名约定指定的内容解析为其他内容,例如:
public class Account
{
[DocumentProperty(Identifier = IdentifierType.Key)]
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
如果您指定 Email
作为 Key 标识符,那么您应该在匿名对象中使用 _key
:
arangoDatabase.Query()
.Upsert(_ => new { _key = insert.Email }
我正在使用 ArangoDatabase 及其驱动程序制作一个带有 CRUD 功能的小型应用程序:
这是我的代码:
var insert = new Account
{
Email = "email01@gmail.com",
FirstName = "Adam",
LastName = "Smith"
};
var update = new Account
{
Email = "email01@gmail.com",
FirstName = "John",
LastName = "Peterson"
};
using (var arangoDatabase = new ArangoDatabase(new DatabaseSharedSetting()
{
Url = "http://127.0.0.1:8529/",
Database = "_system",
Credential = new NetworkCredential()
{
UserName = "root",
Password = "xvxvc"
}
}))
{
arangoDatabase.Query()
.Upsert(_ => new Account() {Email = insert.Email},
_ => insert, ((aql, x) => update))
.In<Account>()
.Execute();
}
第一次 运行,[插入] 对象被添加到数据库中。 因此,我现在的数据库是:
但是在第二次 运行 代码时,它抛出了一个错误:
unique constraint violated (while executing). ErrorNumber: 1210 HttpStatusCode: 409
问题是:我的问题是什么,如何解决?
谢谢,
问题可能是 upsert 搜索表达式序列化:
假设 Account
class 定义为:
public class Account
{
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
upsert 搜索表达式:new Account() {Email = insert.Email}
将序列化为:
{ Email: "email01@gmail.com", FirstName: null, LastName: null }
但预期的是:
{ Email: "email01@gmail.com" }
由于搜索表达式永远找不到文档,因此会发生插入,您会得到 unique constraint violated
.
有两种解决方案可以避免序列化 FirstName
和 LastName
成员:
一个是我们可以使用 Json.net JsonProperty
属性来忽略序列化中的空值:
public class Account
{
public string Email { get; set; }
[Newtonsoft.Json.JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string FirstName { get; set; }
[Newtonsoft.Json.JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string LastName { get; set; }
}
另一种方式是使用匿名对象进行搜索表达式:
arangoDatabase.Query()
.Upsert(_ => new Account() {Email = insert.Email}
// should be
arangoDatabase.Query()
.Upsert(_ => new {Email = insert.Email}
关于使用匿名对象的一个注意事项是 Email
成员可以根据您为其命名约定指定的内容解析为其他内容,例如:
public class Account
{
[DocumentProperty(Identifier = IdentifierType.Key)]
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
如果您指定 Email
作为 Key 标识符,那么您应该在匿名对象中使用 _key
:
arangoDatabase.Query()
.Upsert(_ => new { _key = insert.Email }