为了账号安全,请及时绑定邮箱和手机立即绑定

RavenDB:更新/合并文档中可能不存在的属性的补丁请求

RavenDB:更新/合并文档中可能不存在的属性的补丁请求

C#
慕虎7371278 2021-10-31 19:28:34
我有一个具有以下域模型的文档:class Entity{    ...    Dictionary<string, string> Settings { get; set; }    ...}并且需要更新指定的集合。但不能覆盖-与传入的更新合并。由于我需要以这种方式处理数以千计的文档,因此我选择了PatchCommand以获得更好的性能。得到以下内容:new PatchCommandData{    Key = upd.EntityId,    Patches = new[]    {        // Foreach incoming Setting remove existing value (if any) and add the new one        new PatchRequest        {            Type = PatchCommandType.Modify,            Name = nameof(Entity.Settings),            Nested = upd.UpdatedSettings.Keys                .Select(x => new PatchRequest                {                    Type = PatchCommandType.Unset,                    Name = x                })                .ToArray()                .Union(upd.UpdatedSettings.Keys                .Select(x => new PatchRequest                {                    Type = PatchCommandType.Set,                    Name = x,                    Value = upd.UpdatedSettings[x]                })                .ToList())                .ToArray(),            Value = RavenJToken.FromObject(upd.UpdatedSettings)        }    }}这样就执行了下一次更新:Before: { Setting1 = "Value1", Setting2 = "Value2" }Update request: { Setting2 = "NewValue2", Setting3 = "Value3" }After: { Setting1 = "Value1", Setting2 = "NewValue2", Setting3 = "Value3" }但是.. 总有一个“但是”。如果db 中存在没有 Settings 属性的文档,提供的补丁将引发错误,提示“无法修改设置中的值,因为未找到”。我找不到任何选项可以将补丁模式切换为 Set vs. Modify on the fly。并且没有选项可以加载所有文档、在应用程序端应用更新并更新数千个文档。我能看到的唯一合理的选择是在类构造函数中为 Settings 属性创建 Dictionary 实例。伙计们,你能建议一些其他的选择吗?
查看完整描述

1 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

完毕。您可以在下面找到最终版本。实际上,使用了 ScriptedPatchCommandData。它包含 JavaScript 主体,Raven 将对文档进行评估和执行。从性能的角度来看,它可能不是最佳选择。但事实证明没有什么重要的。希望它可能对某人有帮助。


const string fieldParameterName = "fieldName";

const string valueParameterName = "value";


var patch = updates

    .Select(update => new ScriptedPatchCommandData

    {

        Key = update.EntityId,

        Patch = new ScriptedPatchRequest

        {

            Script = $"this[{fieldParameterName}] = _.assign({{}}, this[{fieldParameterName}], JSON.parse({valueParameterName}));",

            Values = new Dictionary<string, object>

            {

                { 

                     fieldParameterName,

                     nameof(Entity.Settings)

                },

                {

                    valueParameterName,

                    JsonConvert.SerializeObject(update.UpdatedSettings)

                }

            }

        }

    })

    .ToList();


return await DocumentStore.AsyncDatabaseCommands.BatchAsync(patch);


查看完整回答
反对 回复 2021-10-31
  • 1 回答
  • 0 关注
  • 146 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信