/// <summary> /// Builds the <b>Odata</b> <i>update</i> request for the entity. /// </summary> /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> /// <param name="saveArgs">The <see cref="ODataArgs"/>.</param> /// <param name="value">The value to create.</param> /// <returns>The <see cref="HttpRequestMessage"/>.</returns> internal async Task <HttpRequestMessage> BuildUpdateRequestAsync <T>(ODataArgs saveArgs, T value) { if (saveArgs == null) { throw new ArgumentNullException(nameof(saveArgs)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } var request = CreateRequestMessage(saveArgs, DetermineHttpMethod("PATCH", UpdateHttpMethod, saveArgs), saveArgs.Mapper.ODataEntityName, saveArgs.Mapper.GetKeyUrl(value)); SetIfMatchCondition(request, saveArgs, value); var json = saveArgs.Mapper.MapToOData(value, Mapper.OperationTypes.Update); using (var ms = new StringWriter()) using (var jw = new JsonTextWriter(ms) { Formatting = Formatting.None }) { await json.WriteToAsync(jw); request.Content = new StringContent(ms.ToString(), null, "application/json"); } return(request); }
/// <summary> /// Gets the entity for the specified <paramref name="keys"/> (mapping from <typeparamref name="TModel"/> to <typeparamref name="T"/>) asynchronously. /// </summary> /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> /// <typeparam name="TModel">The OData model <see cref="Type"/>.</typeparam> /// <param name="getArgs">The <see cref="ODataArgs{T, TModel}"/>.</param> /// <param name="keys">The key values.</param> /// <returns>The entity value where found; otherwise, <c>null</c>.</returns> public async Task <T?> GetAsync <T, TModel>(ODataArgs <T, TModel> getArgs, params IComparable?[] keys) where T : class, new() where TModel : class, new() { if (getArgs == null) { throw new ArgumentNullException(nameof(getArgs)); } var okeys = getArgs.GetODataKeys(keys); return(await ODataInvoker.Default.InvokeAsync(this, async() => { try { var val = await Client.For <TModel>(getArgs.CollectionName).Key(okeys).FindEntryAsync().ConfigureAwait(false); return GetValue(getArgs, val); } catch (WebRequestException odex) { if (odex.Code == System.Net.HttpStatusCode.NotFound && getArgs.NullOnNotFoundResponse) { return null; } throw; } }, this).ConfigureAwait(false)); }
/// <summary> /// Builds the <b>Odata</b> <i>execute</i> request for the entity. /// </summary> /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> /// <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 value to create.</param> /// <returns>The <see cref="HttpRequestMessage"/>.</returns> /// <remarks>The <see cref="HttpMethod"/> defaults to a <see cref="HttpMethod.Post"/>. This is overridden using the <see cref="ODataArgs.OverrideHttpMethod"/>.</remarks> internal async Task <HttpRequestMessage> BuildExecuteRequestAsync <T>(ODataArgs exeArgs, string pathAndQuery, T value) { if (exeArgs == null) { throw new ArgumentNullException(nameof(exeArgs)); } var request = CreateRequestMessage(exeArgs, DetermineHttpMethod("POST", CreateHttpMethod, exeArgs), exeArgs.Mapper.ODataEntityName, null); request.Headers.IfMatch.Add(EntityTagHeaderValue.Any); if (value != null) { var json = exeArgs.Mapper.MapToOData(value, Mapper.OperationTypes.Any); using (var ms = new StringWriter()) using (var jw = new JsonTextWriter(ms) { AutoCompleteOnClose = true }) { await json.WriteToAsync(jw); request.Content = new StringContent(ms.ToString(), null, "application/json"); } } return(request); }
/// <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); }
/// <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); }
/// <summary> /// Creates and executes a select query creating a resultant collection. /// </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>A resultant collection.</returns> public async Task <TColl> SelectQueryAsync <TColl, T>(ODataArgs queryArgs, Func <IQueryable <T>, IQueryable <T> > query = null) where TColl : ICollection <T>, new() where T : class { var coll = new TColl(); await SelectQueryAsync(queryArgs, coll, query); return(coll); }
/// <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); }
/// <summary> /// Gets the <b>Odata</b> entity for the specified <paramref name="keys"/> mapping to <typeparamref name="T"/>. /// </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 entity value where found; otherwise, <c>null</c>.</returns> public async Task <T> GetAsync <T>(ODataArgs getArgs, params IComparable[] keys) where T : class, new() { return(await ODataInvoker.Default.InvokeAsync(this, async() => { var request = await BuildGetRequestAsync(SetUpArgs <T>(getArgs), keys); OnCreatingRequest(request); var response = await SendRequestAsync(request); getArgs.ResponseMessage = response; return await ProcessGetResponseAsync <T>(response, getArgs); }, this)); }
/// <summary> /// Invoke the GET query using the <paramref name="queryAggregator"/> and add to the <paramref name="coll"/>. /// </summary> /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> /// <param name="queryArgs">The <see cref="ODataArgs"/>.</param> /// <param name="queryAggregator">The <see cref="ODataQueryAggregator"/>.</param> /// <param name="coll">The collection to add items to.</param> internal async Task Query <T>(ODataArgs queryArgs, ODataQueryAggregator queryAggregator, ICollection <T> coll) { await ODataInvoker.Default.InvokeAsync(this, async() => { var request = await BuildQueryRequestAsync(queryArgs, queryAggregator.ToString()); OnCreatingRequest(request); var response = await SendRequestAsync(request); queryArgs.ResponseMessage = response; await ProcessQueryResponse(response, queryArgs, queryAggregator, coll); }, this); }
/// <summary> /// Executes an <b>OData</b> request for a specified <paramref name="pathAndQuery"/> with a <typeparamref name="TReq"/> request value. /// </summary> /// <typeparam name="TReq">The request <see cref="Type"/>.</typeparam> /// <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="Task"/> with no response value.</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 ExecuteAsync <TReq>(ODataArgs exeArgs, string pathAndQuery, TReq value) { await ODataInvoker.Default.InvokeAsync(this, async() => { var request = await BuildExecuteRequestAsync <TReq>(exeArgs, pathAndQuery, value); OnCreatingRequest(request); var response = await SendRequestAsync(request); exeArgs.ResponseMessage = response; EnsureSuccessStatusCodeForResponse(response); }, this); }
/// <summary> /// Executes an <b>OData</b> request for a specified <paramref name="pathAndQuery"/> with a <typeparamref name="TRes"/> response. /// </summary> /// <typeparam name="TRes">The response <see cref="Type"/>.</typeparam> /// <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 resulting value.</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 <TRes> ExecuteAsync <TRes>(ODataArgs exeArgs, string pathAndQuery) { var json = await ExecuteAsync(exeArgs, pathAndQuery, null); if (json == null) { return(default(TRes)); } return((TRes)exeArgs.Mapper.MapFromOData(json, Mapper.OperationTypes.Any)); }
/// <summary> /// Deletes (<see cref="DeleteHttpMethod"/>) the <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> public async Task DeleteAsync <T>(ODataArgs saveArgs, params IComparable[] keys) where T : class, new() { await ODataInvoker.Default.InvokeAsync(this, async() => { var request = await BuildDeleteRequestAsync(SetUpArgs <T>(saveArgs), keys); OnCreatingRequest(request); var response = await SendRequestAsync(request); saveArgs.ResponseMessage = response; EnsureSuccessStatusCodeForResponse(response); }, this); }
/// <summary> /// Executes 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 resulting <see cref="JObject"/>.</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 <JObject> ExecuteAsync(ODataArgs exeArgs, string pathAndQuery, JObject json) { return(await ODataInvoker.Default.InvokeAsync(this, async() => { var request = await BuildExecuteRequestAsync(exeArgs, pathAndQuery, json); OnCreatingRequest(request); var response = await SendRequestAsync(request); exeArgs.ResponseMessage = response; return await ProcessExecuteResponseAsync(response, exeArgs); }, this)); }
/// <summary> /// Executes an <b>OData</b> request for a specified <paramref name="pathAndQuery"/> with a <typeparamref name="TRes"/> response. /// </summary> /// <typeparam name="TRes">The response <see cref="Type"/>.</typeparam> /// <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 resulting value.</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 <TRes> ExecuteAsync <TRes>(ODataArgs exeArgs, string pathAndQuery) { if (exeArgs == null) { throw new ArgumentNullException(nameof(exeArgs)); } var json = await ExecuteAsync(exeArgs, pathAndQuery, null).ConfigureAwait(false); if (json == null) { return(default);
/// <summary> /// Updates (<see cref="UpdateHttpMethod"/>) the <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 value to create.</param> /// <returns>The value (re-queried where specified).</returns> public async Task <T> UpdateAsync <T>(ODataArgs saveArgs, T value) where T : class, new() { return(await ODataInvoker.Default.InvokeAsync(this, async() => { var request = await BuildUpdateRequestAsync <T>(SetUpArgs <T>(saveArgs), value); OnCreatingRequest(request); var response = await SendRequestAsync(request); saveArgs.ResponseMessage = response; EnsureSuccessStatusCodeForResponse(response); return value; }, this)); }
/// <summary> /// Processes the <b>Odata</b> <i>query</i> <see cref="HttpResponseMessage"/>. /// </summary> /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> /// <param name="response">The <see cref="HttpResponseMessage"/>.</param> /// <param name="queryArgs">The <see cref="ODataArgs"/>.</param> /// <param name="queryAggregator">The <see cref="ODataQueryAggregator"/>.</param> /// <param name="coll">The collection to add to.</param> /// <returns>The <see cref="Task"/>.</returns> internal async Task ProcessQueryResponse <T>(HttpResponseMessage response, ODataArgs queryArgs, ODataQueryAggregator queryAggregator, ICollection <T> coll) { EnsureSuccessStatusCodeForResponse(response); var type = typeof(T); IODataMapper mapper = null; PropertyInfo pi = null; switch (queryAggregator.SelectClause.Selector.NodeType) { case System.Linq.Expressions.ExpressionType.MemberAccess: mapper = queryArgs.Mapper; var me = (System.Linq.Expressions.MemberExpression)queryAggregator.SelectClause.Selector; pi = (PropertyInfo)me.Member; break; default: mapper = queryArgs.Mapper.SrceType == type ? queryArgs.Mapper : ODataAutoMapper.GetMapper(type); break; } int?count = null; using (var s = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) using (var sr = new StreamReader(s)) using (var jr = new JsonTextReader(sr)) { var json = await JObject.LoadAsync(jr).ConfigureAwait(false); count = json.Value <int?>("@odata.count"); foreach (var jt in json.GetValue("value")) { var obj = mapper.MapFromOData(jt, Mapper.OperationTypes.Get); if (pi == null) { coll.Add((T)obj); } else { coll.Add((T)pi.GetValue(obj)); } } } if (count.HasValue && queryArgs.Paging != null && queryArgs.Paging.IsGetCount) { queryArgs.Paging.TotalCount = count.Value; } }
/// <summary> /// Builds the <b>Odata</b> <i>delete</i> request for the specified <paramref name="keys"/>. /// </summary> /// <param name="saveArgs">The <see cref="ODataArgs"/>.</param> /// <param name="keys">The key values.</param> /// <returns>The <see cref="HttpRequestMessage"/>.</returns> internal async Task <HttpRequestMessage> BuildDeleteRequestAsync(ODataArgs saveArgs, params IComparable[] keys) { if (saveArgs == null) { throw new ArgumentNullException(nameof(saveArgs)); } if (keys == null || keys.Length == 0) { throw new ArgumentNullException(nameof(keys)); } return(await Task.FromResult(CreateRequestMessage(saveArgs, DetermineHttpMethod("DELETE", DeleteHttpMethod, saveArgs), saveArgs.Mapper.ODataEntityName, saveArgs.Mapper.GetKeyUrl(keys)))); }
/// <summary> /// Gets the model. /// </summary> private async Task <TModel?> GetModelAsync <T, TModel>(ODataArgs <T, TModel> getArgs, object[]?keys) where T : class, new() where TModel : class, new() { try { return(await Client.For <TModel>(getArgs.CollectionName).Key(keys).FindEntryAsync().ConfigureAwait(false)); } catch (WebRequestException odex) { if (odex.Code == System.Net.HttpStatusCode.NotFound && getArgs.NullOnNotFoundResponse) { return(null); } throw; } }
/// <summary> /// Builds the <b>Odata</b> <i>get</i> request for the specified <paramref name="keys"/>. /// </summary> /// <param name="args">The <see cref="ODataArgs"/>.</param> /// <param name="keys">The key values.</param> /// <returns>The <see cref="HttpRequestMessage"/>.</returns> internal async Task <HttpRequestMessage> BuildGetRequestAsync(ODataArgs args, params IComparable[] keys) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (keys == null || keys.Length == 0) { throw new ArgumentNullException(nameof(keys)); } string q = $"{args.Mapper.GetKeyUrl(keys)}?{args.GetODataQuery()}"; return(await Task.FromResult(CreateRequestMessage(args, DetermineHttpMethod("GET", GetHttpMethod, args), args.Mapper.ODataEntityName, q))); }
/// <summary> /// Sets up (creates) and auto-maps the <paramref name="args"/>. /// </summary> /// <typeparam name="T">The <see cref="Type"/>.</typeparam> /// <param name="args">The <see cref="ODataArgs"/>.</param> /// <returns>An updated or created <see cref="ODataArgs"/>.</returns> internal ODataArgs SetUpArgs <T>(ODataArgs args) { var oa = args ?? new ODataArgs(); if (oa.Mapper == null) { oa.Mapper = ODataAutoMapper.GetMapper(typeof(T)); } else if (oa.Mapper.SrceType != typeof(T)) { throw new ArgumentException($"The Entity Type is '{typeof(T).Name}' and the Mapper Type is '{oa.Mapper.SrceType.Name}'; these must be the same."); } args = oa; return(args); }
/// <summary> /// Creates and executes a select query adding to the passed collection. /// </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="coll">The collection to add items to.</param> /// <param name="query">An optional function to enable in-place query selection.</param> public Task SelectQueryAsync <TColl, T>(ODataArgs queryArgs, TColl coll, Func <IQueryable <T>, IQueryable <T> > query = null) where TColl : ICollection <T> where T : class { var q = 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 OdmQueryable<T>."); } return(Task.Run(() => { foreach (var item in q.AsEnumerable()) { coll.Add(item); } })); }
/// <summary> /// Creates the entity (mapping from <typeparamref name="T"/> to <typeparamref name="TModel"/>) asynchronously. /// </summary> /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> /// <typeparam name="TModel">The OData model <see cref="Type"/>.</typeparam> /// <param name="saveArgs">The <see cref="ODataArgs{T, TModel}"/>.</param> /// <param name="value">The value to create.</param> /// <returns>The created entity value.</returns> public async Task <T> CreateAsync <T, TModel>(ODataArgs <T, TModel> saveArgs, T value) where T : class, new() where TModel : class, new() { if (saveArgs == null) { throw new ArgumentNullException(nameof(saveArgs)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } // Note: ChangeLog is not updated (if it exists) as it is assumed the OData data source is responsible for this. return(await ODataInvoker.Default.InvokeAsync(this, async() => { var model = saveArgs.Mapper.MapToDest(value, Mapper.OperationTypes.Create) ?? throw new InvalidOperationException("Mapping to the OData model must not result in a null value."); var created = await Client.For <TModel>(saveArgs.CollectionName).Set(model).InsertEntryAsync(true).ConfigureAwait(false); return GetValue(saveArgs, created); }, this).ConfigureAwait(false));
/// <summary> /// Builds the <b>Odata</b> <i>execute</i> request. /// </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="HttpRequestMessage"/>.</returns> /// <remarks>The <see cref="HttpMethod"/> defaults to a <see cref="HttpMethod.Post"/>. This is overridden using the <see cref="ODataArgs.OverrideHttpMethod"/>.</remarks> internal async Task <HttpRequestMessage> BuildExecuteRequestAsync(ODataArgs exeArgs, string pathAndQuery, JObject json = null) { if (exeArgs == null) { throw new ArgumentNullException(nameof(exeArgs)); } if (string.IsNullOrEmpty(pathAndQuery)) { throw new ArgumentNullException(nameof(pathAndQuery)); } var request = CreateRequestMessage(exeArgs, DetermineHttpMethod("POST", null, exeArgs), null, pathAndQuery); if (json != null) { request.Content = new StringContent(json.ToString(), null, "application/json"); } return(await Task.FromResult(request)); }
/// <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); }
/// <summary> /// Sets the IF-MATCH condition for the eTag. /// </summary> private static void SetIfMatchCondition(HttpRequestMessage request, ODataArgs args, object value) { if (value == null) { return; } switch (args.IfMatch) { case ODataIfMatch.UpdateEtag: if (!(value is IETag etag)) { goto case ODataIfMatch.UpdateAny; } request.Headers.IfMatch.Add(new EntityTagHeaderValue(etag.ETag)); break; case ODataIfMatch.UpdateAny: request.Headers.IfMatch.Add(EntityTagHeaderValue.Any); break; } }
/// <summary> /// Initializes a new instance of the <see cref="ODataQueryable{T}"/> class. /// </summary> /// <param name="odata">The <see cref="ODataBase"/>.</param> /// <param name="queryArgs">The <see cref="ODataArgs"/>.</param> /// <param name="executor">The <see cref="IQueryExecutor"/>.</param> public ODataQueryable(ODataBase odata, ODataArgs queryArgs, ref IQueryExecutor executor) : base(QueryParser.CreateDefault(), CreateExecutor(odata, queryArgs, ref executor)) { QueryExecutor = (ODataQueryExecutor)executor; }
/// <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))); }
/// <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))); }
/// <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))); }
/// <summary> /// Creates an <see cref="ODataQuery{T, TModel}"/> to enable select-like capabilities. /// </summary> /// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> /// <typeparam name="TModel">The OData model <see cref="Type"/>.</typeparam> /// <param name="queryArgs">The <see cref="ODataArgs{T, TModel}"/>.</param> /// <param name="query">The function to further define the query.</param> /// <returns>A <see cref="ODataQuery{T, TModel}"/>.</returns> public ODataQuery <T, TModel> Query <T, TModel>(ODataArgs <T, TModel> queryArgs, Func <Soc.IBoundClient <TModel>, Soc.IBoundClient <TModel> >?query = null) where T : class, new() where TModel : class, new() { return(new ODataQuery <T, TModel>(this, queryArgs, query)); }