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

我有一个具有以下域模型的文档:


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 实例。


伙计们,你能建议一些其他的选择吗?


慕虎7371278
浏览 147回答 1
1回答

慕桂英4014372

完毕。您可以在下面找到最终版本。实际上,使用了 ScriptedPatchCommandData。它包含 JavaScript 主体,Raven 将对文档进行评估和执行。从性能的角度来看,它可能不是最佳选择。但事实证明没有什么重要的。希望它可能对某人有帮助。const string fieldParameterName = "fieldName";const string valueParameterName = "value";var patch = updates&nbsp; &nbsp; .Select(update => new ScriptedPatchCommandData&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Key = update.EntityId,&nbsp; &nbsp; &nbsp; &nbsp; Patch = new ScriptedPatchRequest&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Script = $"this[{fieldParameterName}] = _.assign({{}}, this[{fieldParameterName}], JSON.parse({valueParameterName}));",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Values = new Dictionary<string, object>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fieldParameterName,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nameof(Entity.Settings)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; valueParameterName,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JsonConvert.SerializeObject(update.UpdatedSettings)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; })&nbsp; &nbsp; .ToList();return await DocumentStore.AsyncDatabaseCommands.BatchAsync(patch);
打开App,查看更多内容
随时随地看视频慕课网APP