JsonPatchDocument访问ICollection

Ada*_*man 7 c# patch entity-framework

我正在尝试使用JsonPatchDocument替换列表中的对象,但是当我尝试使用正确的路径访问集合的成员时获取异常,这是我的代码:

    var oppfour = new Operation<Application>("replace", "/comments/0", "", obj);

    var contractResolver = new DefaultContractResolver();
    var operations = new List<Operation<Application>>();

    operations.Add(operation);
    operations.Add(opptwo);
    operations.Add(oppthree);
    operations.Add(oppfour);

    var patchJson = new JsonPatchDocument<Application>(operations, contractResolver);

    try
    {
        patchJson.ApplyTo(app);
    }
Run Code Online (Sandbox Code Playgroud)

我试图访问的数据模型对于Application来说是这样的:

public class Application: BaseEntity
{
    public virtual ICollection<Comment> Comments { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是一个例外:

Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException:找不到路径段"0"指定的目标位置.

如何设置在集合中的特定点替换某些内容的路径?

小智 7

有点老问题了,但是...... JsonPatch 规定它需要一个决定性的路径来操作元素。对于数组,这意味着指定要更新的成员的序号(或“-”表示添加)。在幕后,JsonPatchDocument 实现了一个列表适配器来负责解析要从路径更新的项目。为了确定是否应该应用列表适配器,它会检查是否有任何可以转换为 IList 的内容。

现在使用 EF,通常将子集合实现为 ICollection:

public virtual ICollection<ChildObject> Children { get; set; }
Run Code Online (Sandbox Code Playgroud)

但如果我们看一下继承,我们会发现 IList 实现了 ICollection,而 ICollection 又实现了 IEnumerable。以下是有关该主题的快速阅读: https://medium.com/@kunaltandon.kt/ienumerable-vs-icollection-vs-ilist-vs-iqueryable-in-c-2101351453db

但归根结底是 IList 添加了 JsonPatch 所需的整数索引。因此无法获取 ICollection 上的序数。故事结局。

现在,如果您将子集合实现为 List,甚至 IList,EF 就不会抱怨 - 只要它支持 ICollection,EF 就会很高兴您可以毫无问题地应用您的 JsonPatch。但是,需要考虑的一件事是,除非您专门发出有序查询,否则您的结果应被视为不确定。因此,应用整数索引是一个谎言。

如果您进行了体面的数据库设计并将键和索引放在表上,那么很可能这只是一个肮脏的善意谎言,而不是一件可耻的事情。但这是你的决定。


小智 1

您发送的操作 json 中的路径不是 url 路径,它是应应用操作的目标实体的属性(如 jobject 中的路径)。

代替:

{ "op": "replace", "path": /comments/0" "value": "..." }
Run Code Online (Sandbox Code Playgroud)

和:

{ "op": "replace", "path": "propertyname", "value": "propertyvalue" }
Run Code Online (Sandbox Code Playgroud)

并通过 url 定位实体,例如:

https://yourapiendpoint/comments/0