简体   繁体   English

从客户端删除一个请求中的所有相关OData实体

[英]Delete all related OData entities in one request from client

To use the Northwind database as an example, each Customer has a collection of Orders. 以Northwind数据库为例,每个Customer都有一组Orders。 I would like to remove all of the references between a particular Customer and all their Orders in just one request. 我想在一个请求中删除特定客户与其所有订单之间的所有引用。

It looks like I can do this (based on the spec ) with DELETE http://services.odata.org/V4/Northwind/Northwind.svc/Customers('ANTON')/Orders but I'm wondering if client libraries support this. 看起来我可以用DELETE http://services.odata.org/V4/Northwind/Northwind.svc/Customers('ANTON')/Orders这样做(基于规范 ),但我想知道客户端库是否支持这个。

I'm using Microsoft.OData.Client for a C# client library, Apache Olingo (v4) for Java, and BreezeJS for JavaScript. 我将Microsoft.OData.Client用于C#客户端库,Apache Olingo(v4)用于Java,BreezeJS用于JavaScript。 An example in any of these would be much appreciated. 任何这些中的一个例子将非常感激。

EDIT: Clarified that I am just removing references , not actually deleting the entities themselves. 编辑:澄清我只是删除引用 ,而不是实际删除实体本身。

Just as swl10 said, you need to delete each reference in turn. 正如swl10所说,你需要依次删除每个引用。 But OData supports $batch. 但OData支持$ batch。 You can put all the delete methods in one request. 您可以将所有删除方法放在一个请求中。 Code as following: 代码如下:

DemoService dsc = new DemoService(new Uri("http://services.odata.org/V4/OData/(S(ut2byeiaglm424a0pbovpo33))/OData.svc/"));
var product = dsc.Products.Expand("Categories").Where(p => p.ID == 1).Single();

foreach (var c in product.Categories)
{
    dsc.DeleteLink(product, "Categories", c);
}
dsc.SaveChanges(SaveChangesOptions.BatchWithSingleChangeset);

You will find that this SaveChanges will send only one request $batch. 您会发现此SaveChanges只会发送一个请求$ batch。 In the payload, there are two internal DELETE request. 在有效负载中,有两个内部DELETE请求。

Given the previous clarifications to this question that you wish to remove the references and not the entities themselves, the answer appears to be no, you cannot do what you want to do. 鉴于之前对此问题的澄清,您希望删除引用而不是实体本身,答案似乎是否定的,您不能做您想做的事情。

In OData 4 (the specification you link to), references are obtained using $ref rather than addressing the entity directly. 在OData 4(您链接到的规范)中,使用$ ref获取引用,而不是直接寻址实体。 As a result the link you are interested in is this one: 因此,您感兴趣的链接是这样的:

http://services.odata.org/V4/Northwind/Northwind.svc/Customers('ANTON')/Orders/$ref

Unfortunately you can't do what you want, as the protocol says (improved for grammar): 不幸的是,你不能按照协议所说的那样做你想要的(改进语法):

Resource paths addressing a single entity reference can be used in DELETE requests to unrelate two entities. 可以在DELETE请求中使用寻址单个实体引用的资源路径来使两个实体不相关。 Resource paths addressing a collection of references can be used in DELETE requests if they are followed by the system query option $id identifying one of the entity references in the collection. 如果后面跟着标识集合中某个实体引用的系统查询选项$ id,则可以在DELETE请求中使用寻址引用集合的资源路径。

The specification writers have gone to some trouble to remove the operation you wish to perform from the protocol. 规范编写者在从协议中删除您希望执行的操作时遇到了一些麻烦。 You must DELETE each reference in turn, you can't delete a whole collection of references in one protocol request. 您必须依次删除每个引用,不能删除一个协议请求中的整个引用集合。

Do you want to just remove the reference between Customers('ANTON') and Orders, or remove Orders entities under Customers('ANTON')? 您是要删除Customers('ANTON')和Orders之间的引用,还是删除Customers('ANTON')下的Orders实体?

If you want later, the service should not provide this kind of Delete according to the protocol. 如果您以后想要,服务不应该根据协议提供这种删除。

If you just want to remove the reference, you can try "PATCH" the "Customers('ANTON')" from the client. 如果您只想删除引用,可以从客户端尝试“PATCH”“Customers('ANTON')”。

If I understand correctly, you want to delete parent entity and all of its children? 如果我理解正确,您想要删除父实体及其所有子项? You can follow these: 你可以按照这些:

1/ Deleting Entities and its Navigation Properties which is "simplest approach" suggested by Jay Traband. 1 / 删除实体及其导航属性 ,这是Jay Traband建议的“最简单的方法”。

2/ Another way, you can setDeleted for each entities: 2 /另一种方法,你可以为每个实体设置删除:

var deletedEntities = Array();
Customers.entityAspect.setDeleted();
deletedEntities.push(Customers);
for( var i=0; i<Customers().Orders().length; i++){
    Customers().Orders()[i].entityAspect.setDeleted();
    deletedEntities.push(Customers().Orders()[i]);
}

manager.saveChanges(deletedEntities).then(saveSucceed).fail(saveFailed);

Above are two ways that I used. 以上是我使用的两种方式。 If you find any better solutions, please let me know. 如果您找到更好的解决方案,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM