예제 #1
0
        /// <summary>
        /// Adds a <see cref="HttpRequestMessage"/> to the batch.
        /// </summary>
        /// <param name="requestMessage">The request message.</param>
        internal ODataBatchItem AddRequest(HttpRequestMessage requestMessage)
        {
            var obi = new ODataBatchItem(this)
            {
                RequestMessage = requestMessage
            };

            lock (_lock)
            {
                if (State != ODataBatchState.Ready)
                {
                    throw new InvalidOperationException("Batch is not in a Ready state; no further requests can be added to the batch.");
                }

                if (IsChangeSet && requestMessage.Method == HttpMethod.Get)
                {
                    throw new InvalidOperationException("Batch has been configured as a change set and as such no GET requests are allowed.");
                }

                Items.Add(obi);
            }

            OData.InvokeOnCreatingRequest(requestMessage);
            return(obi);
        }
예제 #2
0
        /// <summary>
        /// Sends the batch and returns an <see cref="ODataBatchResponse"/>.
        /// </summary>
        /// <returns>The <see cref="ODataBatchResponse"/>.</returns>
        public async Task <ODataBatchResponse> SendAsync()
        {
            lock (_lock)
            {
                if (State != ODataBatchState.Ready)
                {
                    throw new InvalidOperationException("Batch is no longer in a Ready state; no further requests can be added to the batch.");
                }

                if (Items.Count == 0)
                {
                    throw new InvalidOperationException("Batch must have add at least one request item added; nothing to send.");
                }

                State = ODataBatchState.Sending;
            }

            return(await ODataInvoker.Default.InvokeAsync(this, async() =>
            {
                var request = OData.CreateRequestMessage(new ODataArgs(), "POST", null, "$batch");
                request.Content = await CreateContentAsync().ConfigureAwait(false);
                var resp = await ODataBatchResponse.CreateAsync(this, await OData.SendRequestAsync(request).ConfigureAwait(false)).ConfigureAwait(false);
                State = ODataBatchState.Sent;
                return resp;
            }, OData).ConfigureAwait(false));
        }
예제 #3
0
        /// <summary>
        /// Batches a <b>Select query</b> for the <b>OData</b> entity.
        /// </summary>
        /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam>
        /// <param name="query">The <see cref="ODataQueryable{T}"/>.</param>
        /// <returns>The <see cref="ODataBatchItem"/>.</returns>
        public async Task <ODataBatchItem> SelectQueryAsync <T>(IQueryable <T> query)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            if (!(query is ODataQueryable <T> q))
            {
                throw new ArgumentException("The query must be an instance of ODataQueryable<T>.", nameof(query));
            }

            if (q.QueryExecutor.OData != this.OData)
            {
                throw new ArgumentException("The query can only be invoked by this batch where both the batch and query are created by the same ODataBase instance.");
            }

            var qa        = q.QueryExecutor.GetQueryAggregator(q.Expression, null);
            var queryArgs = q.QueryExecutor.QueryArgs;
            var obi       = AddRequest(await OData.BuildQueryRequestAsync(queryArgs, q.GetODataQuery(null)).ConfigureAwait(false));

            obi.GetValueFunc = async() =>
            {
                var coll = new List <T>();
                await OData.ProcessQueryResponse(obi.ResponseMessage, queryArgs, qa, coll).ConfigureAwait(false);

                return(coll);
            };

            return(obi);
        }
예제 #4
0
        /// <summary>
        /// Batches an <b>execute</b> of an <b>OData</b> request for a specified <paramref name="pathAndQuery"/> with a <typeparamref name="TReq"/> request and <typeparamref name="TRes"/> response value.
        /// </summary>
        /// <param name="exeArgs">The <see cref="ODataArgs"/>.</param>
        /// <param name="pathAndQuery">The url path and query <see cref="string"/> (excluding the base URI path).</param>
        /// <param name="value">The request value.</param>
        /// <returns>The <see cref="ODataBatchItem"/>.</returns>
        /// <remarks>The <see cref="HttpMethod"/> defaults to a <see cref="HttpMethod.Post"/>. This is overridden using the <see cref="ODataArgs.OverrideHttpMethod"/>.</remarks>
        public async Task <ODataBatchItem> ExecuteAsync <TReq, TRes>(ODataArgs exeArgs, string pathAndQuery, TReq value)
        {
            var obi = AddRequest(await OData.BuildExecuteRequestAsync(exeArgs, pathAndQuery, value).ConfigureAwait(false));

            obi.GetValueFunc = async() => await OData.ProcessExecuteResponseAsync <TRes>(obi.ResponseMessage, exeArgs).ConfigureAwait(false);

            return(obi);
        }
예제 #5
0
        /// <summary>
        /// Batches a <b>Get</b> of an <b>OData</b> entity for the specified <paramref name="keys"/>.
        /// </summary>
        /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam>
        /// <param name="getArgs">The <see cref="ODataArgs"/>.</param>
        /// <param name="keys">The key values.</param>
        /// <returns>The <see cref="ODataBatchItem"/>.</returns>
        public async Task <ODataBatchItem> GetAsync <T>(ODataArgs getArgs, params IComparable[] keys) where T : class, new()
        {
            var obi = AddRequest(await OData.BuildGetRequestAsync(OData.SetUpArgs <T>(getArgs), keys).ConfigureAwait(false));

            obi.GetValueFunc = async() => await OData.ProcessGetResponseAsync <T>(obi.ResponseMessage, getArgs).ConfigureAwait(false);

            return(obi);
        }
예제 #6
0
        /// <summary>
        /// Batches an <b>execute</b> of an <b>OData</b> request for a specified <paramref name="pathAndQuery"/> using a <see cref="JObject"/> for the request and response.
        /// </summary>
        /// <param name="exeArgs">The <see cref="ODataArgs"/>.</param>
        /// <param name="pathAndQuery">The url path and query <see cref="string"/> (excluding the base URI path).</param>
        /// <param name="json">Optional JSON request content.</param>
        /// <returns>The <see cref="ODataBatchItem"/>.</returns>
        /// <remarks>The <see cref="HttpMethod"/> defaults to a <see cref="HttpMethod.Post"/>. This is overridden using the <see cref="ODataArgs.OverrideHttpMethod"/>.</remarks>
        public async Task <ODataBatchItem> ExecuteAsync(ODataArgs exeArgs, string pathAndQuery, JObject json)
        {
            var obi = AddRequest(await OData.BuildExecuteRequestAsync(exeArgs, pathAndQuery, json));

            obi.GetValueFunc = async() => await OData.ProcessExecuteResponseAsync(obi.ResponseMessage, exeArgs);

            return(obi);
        }
예제 #7
0
        /// <summary>
        /// Creates (<see cref="ODataBase.CreateQuery{T}(ODataArgs)"/>) and batches a <b>Select query</b> for the <b>OData</b> entity.
        /// </summary>
        /// <typeparam name="TColl">The collection <see cref="Type"/>.</typeparam>
        /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam>
        /// <param name="queryArgs">The <see cref="ODataArgs"/>.</param>
        /// <param name="query">An optional function to enable in-place query selection.</param>
        /// <returns>The <see cref="ODataBatchItem"/>.</returns>
        public async Task <ODataBatchItem> SelectQueryAsync <TColl, T>(ODataArgs queryArgs, Func <IQueryable <T>, IQueryable <T> > query = null) where TColl : ICollection <T>, new() where T : class
        {
            var q = OData.CreateQuery <T>(queryArgs);

            if (query != null)
            {
                var q2 = query(q) as ODataQueryable <T>;
                q = q2 ?? throw new InvalidOperationException("The query function must return an instance of ODataQueryable<T>.");
            }

            var qa  = q.QueryExecutor.GetQueryAggregator(q.Expression, null);
            var obi = AddRequest(await OData.BuildQueryRequestAsync(queryArgs, qa.ToString()).ConfigureAwait(false));

            obi.GetValueFunc = async() =>
            {
                var coll = new TColl();
                await OData.ProcessQueryResponse(obi.ResponseMessage, queryArgs, qa, coll).ConfigureAwait(false);

                return(coll);
            };

            return(obi);
        }
예제 #8
0
 /// <summary>
 /// Batches an <b>execute</b> of an <b>OData</b> request for a specified <paramref name="pathAndQuery"/> with a <typeparamref name="TReq"/> request value.
 /// </summary>
 /// <param name="exeArgs">The <see cref="ODataArgs"/>.</param>
 /// <param name="pathAndQuery">The url path and query <see cref="string"/> (excluding the base URI path).</param>
 /// <param name="value">The request value.</param>
 /// <returns>The <see cref="ODataBatchItem"/>.</returns>
 /// <remarks>The <see cref="HttpMethod"/> defaults to a <see cref="HttpMethod.Post"/>. This is overridden using the <see cref="ODataArgs.OverrideHttpMethod"/>.</remarks>
 public async Task <ODataBatchItem> ExecuteAsync <TReq>(ODataArgs exeArgs, string pathAndQuery, TReq value)
 {
     return(AddRequest(await OData.BuildExecuteRequestAsync(exeArgs, pathAndQuery, value).ConfigureAwait(false)));
 }
예제 #9
0
 /// <summary>
 /// Batches a <b>Delete</b> of an <b>Odata</b> entity for the specified <paramref name="keys"/>.
 /// </summary>
 /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam>
 /// <param name="saveArgs">The <see cref="ODataArgs"/>.</param>
 /// <param name="keys">The key values.</param>
 /// <returns>The <see cref="ODataBatchItem"/>.</returns>
 public async Task <ODataBatchItem> DeleteAsync <T>(ODataArgs saveArgs, params IComparable[] keys) where T : class, new()
 {
     return(AddRequest(await OData.BuildDeleteRequestAsync(OData.SetUpArgs <T>(saveArgs), keys).ConfigureAwait(false)));
 }
예제 #10
0
 /// <summary>
 /// Batches an <b>Update</b> of an <b>Odata</b> entity.
 /// </summary>
 /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam>
 /// <param name="saveArgs">The <see cref="ODataArgs"/>.</param>
 /// <param name="value">The entity value.</param>
 /// <returns>The <see cref="ODataBatchItem"/>.</returns>
 public async Task <ODataBatchItem> UpdateAsync <T>(ODataArgs saveArgs, T value) where T : class, new()
 {
     return(AddRequest(await OData.BuildUpdateRequestAsync(OData.SetUpArgs <T>(saveArgs), value).ConfigureAwait(false)));
 }
예제 #11
0
 /// <summary>
 /// Batches an <b>execute</b> of an <b>OData</b> request for a specified <paramref name="pathAndQuery"/>.
 /// </summary>
 /// <param name="exeArgs">The <see cref="ODataArgs"/>.</param>
 /// <param name="pathAndQuery">The url path and query <see cref="string"/> (excluding the base URI path).</param>
 /// <returns>The <see cref="ODataBatchItem"/>.</returns>
 /// <remarks>The <see cref="HttpMethod"/> defaults to a <see cref="HttpMethod.Post"/>. This is overridden using the <see cref="ODataArgs.OverrideHttpMethod"/>.</remarks>
 public async Task <ODataBatchItem> ExecuteAsync(ODataArgs exeArgs, string pathAndQuery)
 {
     return(AddRequest(await OData.BuildExecuteRequestAsync(exeArgs, pathAndQuery)));
 }
예제 #12
0
 /// <summary>
 /// Batches a <b>Create</b> of an <b>Odata</b> entity.
 /// </summary>
 /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam>
 /// <param name="saveArgs">The <see cref="ODataArgs"/>.</param>
 /// <param name="value">The entity value.</param>
 /// <returns>The <see cref="ODataBatchItem"/>.</returns>
 public async Task <ODataBatchItem> CreateAsync <T>(ODataArgs saveArgs, T value) where T : class, new()
 {
     return(AddRequest(await OData.BuildCreateRequestAsync(OData.SetUpArgs <T>(saveArgs), value)));
 }