我需要执行原子的“如果不存在添加”逻辑,否则什么也不做,为此我正在使用Upsert。
我的模特:
public class Person
{
[BsonId]
public Guid Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public DateTime ReceivedAt { get; set; }
public List<Person> Children { get; set; }
}
我的代码:
var person = new Person() { Id = Guid.NewGuid(), Name = "name", Title = "title", ReceivedAt = DateTime.Now };
var result = context.People.FindOneAndUpdateAsync<Person>(
x => x.Title == person.Title && x.Name == person.Name && x.ReceivedAt <= person.ReceivedAt + TimeSpan.FromMinutes(1),
Builders<Person>.Update.Combine(),
new FindOneAndUpdateOptions<Person>() { IsUpsert = true });
上面没有插入的文件不存在,我在做什么错?我需要设置IsUpsert以外的其他东西吗?
答案 0 :(得分:0)
在您的代码中result
的类型为Task<Person>
,您在这里错过了await
,这就是为什么您没有看到抛出异常的原因。当您将代码更改为:
var result = col.FindOneAndUpdateAsync<Person>(
x => x.Title == person.Title && x.Name == person.Name && x.ReceivedAt <= person.ReceivedAt + TimeSpan.FromMinutes(1),
Builders<Person>.Update.Combine(),
new FindOneAndUpdateOptions<Person>() { IsUpsert = true })
.GetAwaiter().GetResult(); // or await in front of invocation
您将收到带有以下消息的ArgumentException
:
其他信息:更新必须至少具有1个更新运算符。
因此您不能有空更新。要解决此问题,您可以例如重复使用Title
属性,该属性的工作方式与您的代码期望的完全相同。
var result = col.FindOneAndUpdateAsync<Person>(
x => x.Title == person.Title && x.Name == person.Name && x.ReceivedAt <= person.ReceivedAt + TimeSpan.FromMinutes(1),
Builders<Person>.Update.Set(x => x.Title, person.Title),
new FindOneAndUpdateOptions<Person>() { IsUpsert = true }).GetAwaiter().GetResult();
ReceivedAt
不会被添加,因为您的lambda表达式会转换为$lte
,这不是相等比较(请检查文档here)。您应该在更新部分中明确定义该值。
此更新根据参数中的相等性子句创建基础文档,然后应用参数中的更新表达式。来自的比较操作将不会包含在新文档中。