仅当值尚不存在时,如何才能将值添加到集合中?
How can I add a value to a collection only if the value doesn't already exist?
在 ravendb 中,我正在尝试解决可以同时将多个 url 添加到单个文档的竞争条件。为了安全地执行此操作(而不是在集合中创建重复的条目),我需要在数据库中以原子方式进行条件检查和数组推送。例如,结构可能如下所示:
public class MyData
{
public string Id { get; set; }
public List<string> Urls { get; set; }
}
假设所有这三个操作都是异步发生的:
AddValue("foo");
AddValue("bar");
AddValue("foo");
我正在查看 Patch,但没有看到如何添加条件。谁能给我举个例子说明我该怎么做?
更新
这是我目前使用的
var listing = _session.Query<ListingData>()
.Where(l => l.ListingId == listingId && l.OwnerId == userId)
.ToList().SingleOrDefault();
if (listing == null)
return DataResult.NotFound;
_session.Advanced.Patch(
listing,
l => l.PhotoUrls,
urls => urls.Add(url));
_session.SaveChanges();
如果一切顺利,这似乎暂时有效,但如果有一些情况,例如,发生基于假阴性的应用程序端重试,那么我想我最终会重复,因为
- 为了得到 entity/id
我必须做一个往返
- 该操作只是简单地添加值,而不先检查它是否存在
只需使用补丁脚本即可。
using (var session = store.OpenSession())
{
var listing = _session.Query<ListingData>()
.Where(l => l.ListingId == listingId && l.OwnerId == userId)
.ToList().SingleOrDefault();
session.Advanced.Defer(new PatchCommandData(
id: listing.ListingId,
changeVector: null,
patch: new PatchRequest
{
Script = @"
if (this.PhotoUrls.includes(url))
throw ‘Url already exists’;
this.PhotoUrls.push($newUrl);
",
Values =
{
["newUrl"] = "The Url to add"
}
},
patchIfMissing: null));
session.SaveChanges();
}
参见:
在 ravendb 中,我正在尝试解决可以同时将多个 url 添加到单个文档的竞争条件。为了安全地执行此操作(而不是在集合中创建重复的条目),我需要在数据库中以原子方式进行条件检查和数组推送。例如,结构可能如下所示:
public class MyData
{
public string Id { get; set; }
public List<string> Urls { get; set; }
}
假设所有这三个操作都是异步发生的:
AddValue("foo");
AddValue("bar");
AddValue("foo");
我正在查看 Patch,但没有看到如何添加条件。谁能给我举个例子说明我该怎么做?
更新
这是我目前使用的
var listing = _session.Query<ListingData>()
.Where(l => l.ListingId == listingId && l.OwnerId == userId)
.ToList().SingleOrDefault();
if (listing == null)
return DataResult.NotFound;
_session.Advanced.Patch(
listing,
l => l.PhotoUrls,
urls => urls.Add(url));
_session.SaveChanges();
如果一切顺利,这似乎暂时有效,但如果有一些情况,例如,发生基于假阴性的应用程序端重试,那么我想我最终会重复,因为
- 为了得到 entity/id 我必须做一个往返
- 该操作只是简单地添加值,而不先检查它是否存在
只需使用补丁脚本即可。
using (var session = store.OpenSession())
{
var listing = _session.Query<ListingData>()
.Where(l => l.ListingId == listingId && l.OwnerId == userId)
.ToList().SingleOrDefault();
session.Advanced.Defer(new PatchCommandData(
id: listing.ListingId,
changeVector: null,
patch: new PatchRequest
{
Script = @"
if (this.PhotoUrls.includes(url))
throw ‘Url already exists’;
this.PhotoUrls.push($newUrl);
",
Values =
{
["newUrl"] = "The Url to add"
}
},
patchIfMissing: null));
session.SaveChanges();
}
参见: