Rest 多个POST方法OData Web API。这应该/可能发生吗?
这个问题也许是一个理想的问题 我需要从通过服务代理调用ODataWebAPI的应用程序中创建多个记录 目前,我正在通过多次调用post方法(通过服务代理),然后调用save changes来批处理请求。例如Rest 多个POST方法OData Web API。这应该/可能发生吗?,rest,odata,asp.net-web-api,asp.net-web-api2,Rest,Odata,Asp.net Web Api,Asp.net Web Api2,这个问题也许是一个理想的问题 我需要从通过服务代理调用ODataWebAPI的应用程序中创建多个记录 目前,我正在通过多次调用post方法(通过服务代理),然后调用save changes来批处理请求。例如 container.AddToColours(new Colour { Id = 1, Name = "Green" }); container.AddToColours(new Colour { Id = 2, Name = "Orange" }); contain
container.AddToColours(new Colour { Id = 1, Name = "Green" });
container.AddToColours(new Colour { Id = 2, Name = "Orange" });
container.SaveChanges(SaveChangesOptions.Batch);
这样做的缺点是,在我的web api控制器中,post方法被调用两次,因此生成两条insert语句
现在,如果我的当事人这样做了
container.AddToColours(new List<Colour>() { new Colour { Id = 1, Name = "Green" }, new Colour { Id = 2, Name = "Orange" }});
container.SaveChanges(SaveChangesOptions.Batch);
container.addToColor(新列表(){new color{Id=1,Name=“Green”},新颜色{Id=2,Name=“Orange”});
container.SaveChanges(SaveChangesOptions.Batch);
然后只创建一条insert语句,同时插入两条记录
问题是,
这可能吗?(我可能会有两种POST方法——一种是单一颜色,另一种是接受颜色列表)
这是否可以通过服务代理实现
这是否违反了OData/REST手册中的所有/任何规则
这是否合乎道德
这是淘气吗
编辑
重温这一点后,我能够创建一个定制的批处理程序,如下所示。我希望这能帮助其他人。它将在单个事务中保存批次中所做的所有更改,因此,如果批次的一部分失败,则所有部分都会失败。但是,重要的是,不管以前的成功或失败,都会尝试为批处理中的所有操作保存,因此可以返回错误消息进行操作
我使用这里的样本作为基础:
但作出了以下改变:
已将EntityFrameworkBatchHandler.ExecuteChangeSet方法更改为:
private async Task ExecuteChangeSet(ChangeSetRequestItem changeSet, IList<ODataBatchResponseItem> responses, CancellationToken cancellation)
{
using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadUncommitted }, TransactionScopeAsyncFlowOption.Enabled))
{
responses.Add((ChangeSetResponseItem) await new ChangeSetBatchRequestItem(changeSet).SendRequestAsync(Invoker, cancellation));
if (responses.All(x => (x as ChangeSetResponseItem).Responses.All(y => y.IsSuccessStatusCode)))
{
scope.Complete();
}
}
}
private async Task ExecuteChangeSet(ChangeSetRequestItem变更集、IList响应、CancellationToken取消)
{
使用(var scope=new TransactionScope(TransactionScopeOption.Required,new TransactionOptions(){IsolationLevel=IsolationLevel.ReadUncommitted},TransactionScopeAsyncFlowOption.Enabled))
{
Add((ChangeSetResponseItem)等待新的ChangeSetBatchRequestItem(changeSet).SendRequestAsync(调用者,取消));
if(responses.All(x=>(x为ChangeSetResponseItem.responses.All(y=>y.IsSuccessStatusCode)))
{
scope.Complete();
}
}
}
我相信这意味着它与EF完全无关。我删除了HttpRequestMessageExtensions.cs并创建了一个新类ChangeSetBatchRequestItem,它与System.Web.OData.Batch.ChangeSetRequestItem完全相同,除了以下方法:
public override async Task<ODataBatchResponseItem> SendRequestAsync(HttpMessageInvoker invoker, CancellationToken cancellationToken)
{
if (invoker == null)
{
throw new ArgumentNullException("invoker");
}
Dictionary<string, string> contentIdToLocationMapping = new Dictionary<string, string>();
List<HttpResponseMessage> responses = new List<HttpResponseMessage>();
try
{
foreach (HttpRequestMessage request in Requests)
{
responses.Add(await SendMessageAsync(invoker, request, cancellationToken, contentIdToLocationMapping));
}
}
catch
{
DisposeResponses(responses);
throw;
}
return new ChangeSetResponseItem(responses);
}
public override async Task SendRequestAsync(HttpMessageInvoker调用程序,CancellationToken CancellationToken)
{
if(调用程序==null)
{
抛出新的ArgumentNullException(“调用程序”);
}
Dictionary contentIdToLocationMapping=新字典();
列表响应=新列表();
尝试
{
foreach(请求中的HttpRequestMessage请求)
{
Add(等待SendMessageAsync(调用程序、请求、取消令牌、contentIdToLocationMapping));
}
}
抓住
{
处置响应(响应);
投掷;
}
返回新的ChangeSetResponseItem(响应);
}
谢谢你的回答,这里是我对你问题的回答
允许并记录在批次处理下的OData规范中。我看不出为什么会是“不道德的”或“顽皮的”。在“这可能吗”中“这”是什么意思?@TanJinfu-这可能吗:我的建议意味着我的OData Web API控制器中将有两个POST方法。一个接受颜色类型的对象,另一个接受颜色类型的集合。当我调用container.addtocolors时,我在我的应用程序中发现了一个问题,它如何知道使用什么post方法?@SimonBelanger;如果有文档记录,是否有通过服务代理实现的方法?当container.SaveChanges(SaveChangesOptions.Batch)时,对container.addToColor的每次调用都会导致对Web API控制器的POST方法的单独调用;被称为。我将如何使它调用后的方法,一旦发送每一个新的颜色?谢谢你的答复。我来看看。您知道有没有一种方法可以在批处理时不导致数据库被命中两次?我想这涉及到使用自定义批处理而不是标准路由。我不确定,但我认为这涉及到使用自定义批处理程序而不是路由。