public void SingleChangesetShouldBeAtomic() { this.TestClientContext.MergeOption = MergeOption.OverwriteChanges; SaveChangesOptions[] options = new SaveChangesOptions[] { // All modifications share one changeset SaveChangesOptions.BatchWithSingleChangeset, // Each modification uses seperate changeset SaveChangesOptions.BatchWithIndependentOperations }; Airline airline = new Airline() { Name = "American Delta", AirlineCode = "DL", TimeStampValue = new byte[] { 0 } }; Airline airline1 = new Airline() { Name = "American Delta", AirlineCode = "DL", TimeStampValue = new byte[] { 0 } }; Flight flight = new Flight() { ConfirmationCode = "JH58496", FlightNumber = "DL589", StartsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 15, 00, 0)), EndsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 16, 30, 0)), AirlineId = "DL", SeatNumber = "C32", FromId = "KSEA", ToId = "ZSSS", Airline = airline }; foreach (var option in options) { this.TestClientContext.ResetDataSource().Execute(); this.TestClientContext.AddToAirlines(airline); this.TestClientContext.AddToFlights(flight); // Post an entity with same ID, this would cause creation failture. this.TestClientContext.AddToAirlines(airline1); switch (option) { case SaveChangesOptions.BatchWithIndependentOperations: DataServiceResponse response1 = this.TestClientContext.SaveChanges(option); Assert.Equal(200, response1.BatchStatusCode); Assert.True(response1.IsBatchResponse); Assert.Equal(3, response1.Count()); var result = response1.ToList(); // 3rd operation would fail, but new flight entry would be inserted. Assert.Equal(201, result[0].StatusCode); Assert.Equal(201, result[1].StatusCode); Assert.Equal(500, result[2].StatusCode); Assert.Equal(1, this.TestClientContext .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count); break; case SaveChangesOptions.BatchWithSingleChangeset: bool exc = false; try { // The single changeset would fail. this.TestClientContext.SaveChanges(option); } catch (Exception) { exc = true; } Assert.True(exc); Assert.Equal(0, this.TestClientContext .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count); break; } this.TestClientContext.Detach(airline1); this.TestClientContext.Detach(airline); this.TestClientContext.Detach(flight); } }
/// <summary> /// constructor for SaveResult /// </summary> /// <param name="context">context</param> /// <param name="method">method</param> /// <param name="options">options</param> /// <param name="callback">user callback</param> /// <param name="state">user state object</param> internal SaveResult(DataServiceContext context, string method, SaveChangesOptions options, AsyncCallback callback, object state) : base(context, method, null, options, callback, state) { Debug.Assert(!Util.IsBatch(this.Options), "Util.IsBatch(this.Options) is not set"); this.cachedResponses = new List<CachedResponse>(); }
private SaveChangesResultCollection CreateSaveChangesResultCollection(SaveChangesOptions option) { var con = typeof(SaveChangesResultCollection).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(); var results = con.Invoke(new object[] { option }) as SaveChangesResultCollection; return(results); }
public void AddObjectTestAction(ODataFormat format, MergeOption mergeOption, SaveChangesOptions saveChangesOption) { DataServiceContextWrapper <DefaultContainer> contextWrapper = this.CreateContext(); contextWrapper.Context.MergeOption = mergeOption; if (format == ODataFormat.Json) { contextWrapper.Format.UseJson(); } contextWrapper.Configurations.RequestPipeline .OnEntryStarting(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntity_Writing) .OnEntryEnding(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntry_Writing); Customer customer = PipelineEventsTestsHelper.CreateNewCustomer(100); contextWrapper.AddObject("Customer", customer); contextWrapper.SaveChanges(saveChangesOption); Assert.IsTrue(customer.Name.EndsWith("UpdatedODataEntryPropertyValue"), "Unexpected primitive property"); Assert.IsTrue(customer.Auditing.ModifiedBy.Equals("UpdatedODataEntryPropertyValue"), "Unexpected complex property"); Assert.IsTrue(customer.PrimaryContactInfo.EmailBag.Contains("UpdatedODataEntryPropertyValue")); contextWrapper.DeleteObject(customer); contextWrapper.SaveChanges(); }
public async new Task <DataServiceResponse> SaveChangesAsync(SaveChangesOptions options) { try { var result = await Task.Factory.FromAsync( BeginSaveChanges, new Func <IAsyncResult, DataServiceResponse>(EndSaveChanges), options, null, TaskCreationOptions.None); foreach (var i in _modifiedEntities) { i.ResetChanges(); } _modifiedEntities.Clear(); return(result); } catch (Exception ex) { var newException = ProcessException(ex); if (newException != null) { throw newException; } throw; } }
/// <summary> /// constructor for BatchSaveResult /// </summary> /// <param name="context">context</param> /// <param name="method">method</param> /// <param name="queries">queries</param> /// <param name="options">options</param> /// <param name="callback">user callback</param> /// <param name="state">user state object</param> internal BatchSaveResult(DataServiceContext context, string method, DataServiceRequest[] queries, SaveChangesOptions options, AsyncCallback callback, object state) : base(context, method, queries, options, callback, state) { Debug.Assert(Util.IsBatch(options), "the options must have batch flag set"); this.Queries = queries; this.streamCopyBuffer = new byte[StreamCopyBufferSize]; }
/// <summary> /// constructor for SaveResult /// </summary> /// <param name="context">context</param> /// <param name="method">method</param> /// <param name="options">options</param> /// <param name="callback">user callback</param> /// <param name="state">user state object</param> internal SaveResult(DataServiceContext context, string method, SaveChangesOptions options, AsyncCallback callback, object state) : base(context, method, null, options, callback, state) { Debug.Assert(!Util.IsBatch(this.Options), "Util.IsBatch(this.Options) is not set"); this.cachedResponses = new List <CachedResponse>(); }
public void PostFullPropertiesInBatch() { var batchFlags = new SaveChangesOptions[] { SaveChangesOptions.BatchWithSingleChangeset, SaveChangesOptions.BatchWithIndependentOperations }; foreach (var batchFlag in batchFlags) { List <ODataResource> entries = new List <ODataResource>(); this.TestClientContext.Configurations.RequestPipeline.OnEntryEnding((arg) => { entries.Add(arg.Entry); }); DataServiceCollection <CustomerPlus> people = new DataServiceCollection <CustomerPlus>(this.TestClientContext, "People", null, null); var person = new CustomerPlus(); people.Add(person); person.FirstNamePlus = "Nelson"; person.LastNamePlus = "Black"; person.NumbersPlus = new ObservableCollection <string> { }; person.EmailsPlus = new ObservableCollection <string> { "*****@*****.**" }; person.PersonIDPlus = 10001; person.CityPlus = "London"; person.TimeBetweenLastTwoOrdersPlus = new TimeSpan(1); person.HomeAddressPlus = new HomeAddressPlus() { CityPlus = "Redmond", PostalCodePlus = "98052", StreetPlus = "1 Microsoft Way" }; DataServiceCollection <AccountPlus> accounts = new DataServiceCollection <AccountPlus>(this.TestClientContext); var account = new AccountPlus(); accounts.Add(account); account.AccountIDPlus = 110; account.CountryRegionPlus = "CN"; DataServiceCollection <ProductPlus> products = new DataServiceCollection <ProductPlus>(this.TestClientContext); ProductPlus product = new ProductPlus(); products.Add(product); product.NamePlus = "Apple"; product.ProductIDPlus = 1000000; product.QuantityInStockPlus = 20; product.QuantityPerUnitPlus = "Pound"; product.UnitPricePlus = 0.35f; product.DiscontinuedPlus = false; product.CoverColorsPlus = new ObservableCollection <ColorPlus>(); //Post entity into an entity set this.TestClientContext.SaveChanges(batchFlag); Assert.Equal(10, entries.Where(e => e.TypeName.Contains("CustomerPlus")).First().Properties.Count()); Assert.Equal(2, entries.Where(e => e.TypeName.Contains("AccountPlus")).First().Properties.Count()); Assert.Equal(9, entries.Where(e => e.TypeName.Contains("ProductPlus")).First().Properties.Count()); } }
public void AddObjectTestAction(ODataFormat format, MergeOption mergeOption, SaveChangesOptions saveChangesOption) { DataServiceContextWrapper <DefaultContainer> contextWrapper = this.CreateContext(); contextWrapper.Context.MergeOption = mergeOption; if (format == ODataFormat.Json) { contextWrapper.Format.UseJson(); } contextWrapper.Configurations.RequestPipeline .OnEntryStarting(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntity_Writing) .OnEntryEnding(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntry_Writing); Customer customer = PipelineEventsTestsHelper.CreateNewCustomer(1100); contextWrapper.AddObject("Customer", customer); IAsyncResult r1 = contextWrapper.BeginSaveChanges( saveChangesOption, result => { contextWrapper.EndSaveChanges(result); }, null); while (!r1.IsCompleted) { Thread.Sleep(1000); } if (format == ODataFormat.Atom) { // Make the ATOM payload order consistence with JSON. Assert.IsTrue(customer.Name.EndsWith("UpdatedODataEntryPropertyValueModifyPropertyValueCustomerEntry_Writing"), "Unexpected primitive property"); } else { Assert.IsTrue(customer.Name.EndsWith("UpdatedODataEntryPropertyValue"), "Unexpected primitive property"); } Assert.IsTrue(customer.Auditing.ModifiedBy.Equals("UpdatedODataEntryPropertyValue"), "Unexpected complex property"); Assert.IsTrue(customer.PrimaryContactInfo.EmailBag.Contains("UpdatedODataEntryPropertyValue")); contextWrapper.DeleteObject(customer); IAsyncResult r2 = contextWrapper.BeginSaveChanges( saveChangesOption, result => { contextWrapper.EndSaveChanges(result); }, null); while (!r2.IsCompleted) { Thread.Sleep(1000); } }
/// <summary> /// Wrapper entry for the DataServiceContext.SaveChanges method. /// </summary> /// <param name="options">options on how to save changes</param> /// <returns>changeset response</returns> public DataServiceResponse SaveChanges(SaveChangesOptions options) { #if SILVERLIGHT || PORTABLELIB throw new NotImplementedException(); #else return(this.wrappedInstance.SaveChanges(options)); #endif }
/// <summary> /// Wrapper entry for the DataServiceContext.SaveChanges method. /// </summary> /// <param name="options">options on how to save changes</param> /// <returns>changeset response</returns> public DataServiceResponse SaveChanges(SaveChangesOptions options) { #if (NETCOREAPP1_0 || NETCOREAPP2_0) throw new NotImplementedException(); #else return(this.wrappedInstance.SaveChanges(options)); #endif }
public static Task<DataServiceResponse> SaveChangesWithRetriesAsync(this TableServiceContext context, SaveChangesOptions options) { return Task.Factory.FromAsync<SaveChangesOptions, DataServiceResponse>(context.BeginSaveChangesWithRetries, context.EndSaveChangesWithRetries, options, null); }
public override object GetResults(IAsyncResult async) { object[] state = (object[])async.AsyncState; SaveChangesOptions option = (SaveChangesOptions)state[0]; DataServiceContext context = (DataServiceContext)state[1]; return(context.EndSaveChanges(async)); }
public ICancellableAsyncResult BeginSaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) { requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); TableCommand <DataServiceResponse, DataServiceResponse> cmd = this.GenerateSaveChangesCommand(options, requestOptions); return(TableExecutor.BeginExecuteAsync(cmd, requestOptions.RetryPolicy, operationContext, callback, state)); }
/// <summary> /// Initializes a new instance of the PipelineEmulator class /// </summary> /// <param name="parent">The parent instance to get dependencies from</param> /// <param name="contextData">The current context data</param> /// <param name="propertyValuesBeforeSave">The property values of the tracked client objects before the call to SaveChanges</param> /// <param name="options">The current save-changes options</param> /// <param name="requestResponsePairs">The observed http traffic for the current save-changes call</param> public PipelineEmulator(SaveChangesHttpValidatingEmulator parent, DataServiceContextData contextData, IDictionary <object, IEnumerable <NamedValue> > propertyValuesBeforeSave, SaveChangesOptions options, IEnumerable <KeyValuePair <IHttpRequest, HttpResponseData> > requestResponsePairs) { this.parent = parent; this.contextData = contextData; this.propertyValuesBeforeSave = propertyValuesBeforeSave; this.options = options; this.httpQueue = new Queue <KeyValuePair <IHttpRequest, HttpResponseData> >(requestResponsePairs); }
/// <summary> /// Begins an asynchronous operation to save changes, using the retry policy specified for the service context. /// </summary> /// <param name="options">Additional options for saving changes.</param> /// <param name="callback">The callback delegate that will receive notification when the asynchronous operation completes.</param> /// <param name="state">A user-defined object that will be passed to the callback delegate.</param> /// <returns>An <see cref="IAsyncResult"/> that references the asynchronous operation.</returns> public IAsyncResult BeginSaveChangesWithRetries(SaveChangesOptions options, AsyncCallback callback, object state) { return(TaskImplHelper.BeginImplWithRetry <DataServiceResponse>( (setResult) => this.SaveChangesWithRetriesImpl(options, setResult), RetryPolicy, callback, state)); }
/// <summary> /// Saves the changes with retries implementation. /// </summary> /// <param name="options">The options for saving changes.</param> /// <param name="setResult">The action to set result.</param> /// <returns>A sequence of tasks to perform the operation.</returns> private TaskSequence SaveChangesWithRetriesImpl(SaveChangesOptions options, Action <DataServiceResponse> setResult) { var task = this.SaveChangesAsync(options); yield return(task); setResult(task.Result); }
public DataServiceResponse SaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions = null, OperationContext operationContext = null) { requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); TableCommand <DataServiceResponse, DataServiceResponse> cmd = this.GenerateSaveChangesCommand(options, requestOptions); return(TableExecutor.ExecuteSync(cmd, requestOptions.RetryPolicy, operationContext)); }
/// <summary> /// Validates the requests sent, updates the expected state, and produces the expected response data for a single call to SaveChanges /// </summary> /// <param name="contextData">The context data at the time save-changes was called</param> /// <param name="propertyValuesBeforeSave">The property values of the tracked client objects before the call to SaveChanges</param> /// <param name="options">The save changes options used</param> /// <param name="requestResponsePairs">The observed HTTP traffic during save-changes</param> /// <returns>The expected response data</returns> public DataServiceResponseData ValidateAndTrackChanges(DataServiceContextData contextData, IDictionary<object, IEnumerable<NamedValue>> propertyValuesBeforeSave, SaveChangesOptions options, IEnumerable<KeyValuePair<HttpRequestData, HttpResponseData>> requestResponsePairs) { ExceptionUtilities.CheckArgumentNotNull(contextData, "contextData"); ExceptionUtilities.CheckArgumentNotNull(requestResponsePairs, "requestResponsePairs"); var castPairs = requestResponsePairs.Select(p => new KeyValuePair<IHttpRequest, HttpResponseData>(p.Key, p.Value)); var emulator = new PipelineEmulator(this, contextData, propertyValuesBeforeSave, options, castPairs); return emulator.Run(); }
public Task <IMediaDataServiceResponse> SaveChangesAsync(SaveChangesOptions options, object state, CancellationToken token) { Task <DataServiceResponse> task = Task.Factory.FromAsync <SaveChangesOptions, DataServiceResponse>( _dataContext.BeginSaveChanges, _dataContext.EndSaveChanges, options, state).HandleCancellation(token); return(task.ContinueWith <IMediaDataServiceResponse>(t => WrapTask(t))); }
/// <summary> /// checks whether the batch flag with independent Operation per change set is set /// </summary> /// <param name="options">options as specified by the user.</param> /// <returns>true if the given flag is set, otherwise false.</returns> internal static bool IsBatchWithIndependentOperations(SaveChangesOptions options) { if (Util.IsFlagSet(options, SaveChangesOptions.BatchWithIndependentOperations)) { Debug.Assert(!Util.IsFlagSet(options, SaveChangesOptions.BatchWithSingleChangeset), "!Util.IsFlagSet(options, SaveChangesOptions.BatchWithSingleChangeset)"); return(true); } return(false); }
private void SetDefaultAcceptHeader(ExpectedClientRequest request, SaveChangesOptions options) { request.Headers[HttpHeaders.Accept] = string.IsNullOrWhiteSpace(this.ClientRequestAcceptHeader) ? DefaultAccept : this.ClientRequestAcceptHeader; #if !SILVERLIGHT request.Headers[HttpHeaders.AcceptCharset] = DefaultEncoding; #else // Silverlight does not specify AcceptCharset at the top level "because the http stack does not support it" request.Headers[HttpHeaders.AcceptCharset] = (options == SaveChangesOptions.Batch) ? DefaultEncoding : null; #endif }
/// <summary> /// Saves the changes for the given CRM organization context. /// </summary> /// <param name="saveChangesOptions">SaveChangesOptions</param> /// <returns>A collection of the action results <see cref="SaveChangesResultCollection"/> class.</returns> public virtual SaveChangesResultCollection SaveChanges(SaveChangesOptions saveChangesOptions) { Trace(string.Format(CultureInfo.InvariantCulture, TraceMessageHelper.EnteredMethod, SystemTypeName, MethodBase.GetCurrentMethod().Name)); SaveChangesResultCollection scrc = OrganizationServiceContext.SaveChanges(saveChangesOptions); Trace(string.Format(CultureInfo.InvariantCulture, TraceMessageHelper.ExitingMethod, SystemTypeName, MethodBase.GetCurrentMethod().Name)); return(scrc); }
/// <summary> /// Saves the changes asynchronously. /// </summary> /// <param name="options">The options.</param> /// <param name="state">The state.</param> /// <returns>A function delegate that returns the future result to be available through the Task.</returns> public Task <IMediaDataServiceResponse> SaveChangesAsync(SaveChangesOptions options, object state) { Task <DataServiceResponse> task = Task.Factory.FromAsync <SaveChangesOptions, DataServiceResponse>( _dataContext.BeginSaveChanges, _dataContext.EndSaveChanges, options, state); return(task.ContinueWith <IMediaDataServiceResponse>(t => WrapTask(t), TaskContinuationOptions.AttachedToParent)); }
// [DataRow(SaveChangesOptions.BatchWithSingleChangeset)] public async Task References(SaveChangesOptions saveChangesOptions) { var book = new Book() { Id = "Id" + RandomInt(), Title = "Title " + RandomInt() }; var publisher = new Publisher() { Title = "New Publisher " + RandomInt() }; var author = new Author() { LastName = "New Publisher " + RandomInt() }; dataServiceContext.AddObject(author); dataServiceContext.AddObject(publisher); dataServiceContext.AddObject(book); dataServiceContext.AddLink(publisher, Pluralize <Book>(), book); dataServiceContext.AddLink(author, Pluralize <Book>(), book); var dataServiceResponse = await dataServiceContext.SaveChangesAsync(saveChangesOptions); dataServiceResponse.Select(c => c.StatusCode).SequenceEqual(new[] { 201, 201, 204 }); var authorWithBooks = await GetAuthorAsync(author.Id); authorWithBooks.Should().NotBeNull("Author was saved"); authorWithBooks.Books.Any().Should().BeTrue("Book was added to author"); var publisherWithBooks = await GetPublisherAsync(publisher); publisherWithBooks.Should().NotBeNull("Publisher was saved"); publisherWithBooks.Books.Any().Should().BeTrue("Book was added to publisher"); var bookWithPublisher = await GetBookAsync(book.Id); bookWithPublisher.Publisher.Should().NotBeNull("Reference was added"); dataServiceContext.DeleteLink(publisher, "Books", book); dataServiceResponse = await dataServiceContext.SaveChangesAsync(saveChangesOptions); bookWithPublisher = await GetBookAsync(book.Id); bookWithPublisher.Publisher.Should().BeNull("Reference was removed"); dataServiceContext.DeleteObject(book); dataServiceContext.DeleteObject(author); dataServiceContext.DeleteObject(publisher); dataServiceResponse = await dataServiceContext.SaveChangesAsync(saveChangesOptions); (await GetPublisherAsync(publisher)).Should().BeNull("Publisher was deleted"); }
/// <param name="deferSaveChanges">true to delay saving until batch is saved; false to save immediately.</param> /// <param name="saveChangesOption">Save changes option to control how change requests are sent to the service.</param> public Task SaveChangesAsync(bool deferSaveChanges = false, SaveChangesOptions saveChangesOption = SaveChangesOptions.None) { if (deferSaveChanges) { var retVal = new TaskCompletionSource <object>(); retVal.SetResult(null); return(retVal.Task); } return(Context.SaveChangesAsync(saveChangesOption)); }
private static Action AddObjectWithInjectedObjectDisposedOnGetStreamO(SaveChangesOptions saveChangesOptions) { IODataRequestMessage requestMessage = new ODataTestMessage(); var responseMessage = CreateResponseMessageWithGetStreamThrowingObjectDisposeException(); var context = new DataServiceContextWithCustomTransportLayer(ODataProtocolVersion.V4, requestMessage, responseMessage); context.AddObject("Products", new SimpleNorthwind.Product() { ID = 1 }); return(() => context.SaveChanges(saveChangesOptions)); }
private List <Exception> SaveConcurrent(int numberOfCalls, SaveChangesOptions options) { // Do several calls to force some timeouts // or manually disconnect the network while this test is running. string partitionKey = Guid.NewGuid().ToString(); var exceptions = new ConcurrentBag <Exception>(); var entities = Enumerable.Range(0, numberOfCalls) .Select(x => new TestServiceEntity { PartitionKey = partitionKey, RowKey = x.ToString() }) .ToList(); var barrier = new Barrier(numberOfCalls); var countdown = new CountdownEvent(numberOfCalls); foreach (var entity in entities) { ThreadPool.QueueUserWorkItem(x => { try { var client = account.CreateCloudTableClient(); client.RetryPolicy = RetryPolicies.NoRetry(); // Explicitly set a VERY short timeout, to force a timeout very frequently. client.Timeout = TimeSpan.FromSeconds(1); var context = client.GetDataServiceContext(); context.AddObject(tableName, x); barrier.SignalAndWait(); context.SaveChanges(options); } catch (Exception ex) { exceptions.Add(ex); } finally { countdown.Signal(); } }, entity); } countdown.Wait(); if (exceptions.Count == 0) { Assert.Inconclusive("No exceptions were thrown to check if they are transient"); } return(exceptions.ToList()); }
/// <summary> /// Executes SaveChanges on the specified context and with specified options and verifies the results. /// </summary> /// <param name="verifier">The verifier to use for verification.</param> /// <param name="contextData">The data for the context.</param> /// <param name="context">The context to verify SaveChanges on.</param> /// <param name="options">The options for saving changes.</param> /// <returns>The response from SaveChanges</returns> public static DSClient.DataServiceResponse VerifySaveChanges(this ISaveChangesVerifier verifier, DataServiceContextData contextData, DSClient.DataServiceContext context, SaveChangesOptions? options) { #if SILVERLIGHT throw new TaupoNotSupportedException("Not supported in Silverlight"); #else ExceptionUtilities.CheckArgumentNotNull(verifier, "verifier"); ExceptionUtilities.CheckArgumentNotNull(contextData, "contextData"); ExceptionUtilities.CheckArgumentNotNull(context, "context"); DSClient.DataServiceResponse response = null; SyncHelpers.ExecuteActionAndWait(c1 => verifier.VerifySaveChanges(c1, contextData, context, options, (c2, r) => { response = r; c2.Continue(); })); return response; #endif }
internal static HttpVerb GetUpdateVerb(SaveChangesOptions options) { if (options == SaveChangesOptions.ReplaceOnUpdate) { return(HttpVerb.Put); } else if (options == SaveChangesOptions.PatchOnUpdate) { return(HttpVerb.Patch); } else { return(HttpVerb.Patch); } }
internal BaseSaveResult(DataServiceContext context, string method, DataServiceRequest[] queries, SaveChangesOptions options, AsyncCallback callback, object state) : base(context, method, callback, state) { this.RequestInfo = new RequestInfo(context); this.Options = options; this.SerializerInstance = new Serializer(this.RequestInfo, options); if (null == queries) { #region changed entries this.ChangedEntries = context.EntityTracker.Entities.Cast<Descriptor>() .Union(context.EntityTracker.Links.Cast<Descriptor>()) .Union(context.EntityTracker.Entities.SelectMany(e => e.StreamDescriptors).Cast<Descriptor>()) .Where(o => o.IsModified && o.ChangeOrder != UInt32.MaxValue) .OrderBy(o => o.ChangeOrder) .ToList(); foreach (Descriptor e in this.ChangedEntries) { e.ContentGeneratedForSave = false; e.SaveResultWasProcessed = 0; e.SaveError = null; if (e.DescriptorKind == DescriptorKind.Link) { object target = ((LinkDescriptor)e).Target; if (null != target) { Descriptor f = context.EntityTracker.GetEntityDescriptor(target); if (EntityStates.Unchanged == f.State) { f.ContentGeneratedForSave = false; f.SaveResultWasProcessed = 0; f.SaveError = null; } } } } #endregion } else { this.ChangedEntries = new List<Descriptor>(); } }
private HttpRequestData CreateUpdateRequest(SaveChangesOptions options, EntityDescriptorData entityDescriptorData) { HttpVerb updateVerb = HttpVerb.Patch; if (options == SaveChangesOptions.ReplaceOnUpdate) { updateVerb = HttpVerb.Put; } else if (options == SaveChangesOptions.PatchOnUpdate) { updateVerb = HttpVerb.Patch; } return(new HttpRequestData() { Verb = updateVerb, Uri = entityDescriptorData.EditLink, }); }
/// <summary> /// Overrides the base OnSavingChangesMethod /// For each entity, determines if an update is required. /// If no update is required, it detaches and reattaches to set the entity back to a "unchanged" state. /// Also create the entity that will ACTUALLY be subitted to the database (used in the OnExecuting method). /// </summary> /// <param name="options">Save changes options.</param> protected override void OnSavingChanges(SaveChangesOptions options) { // Clear the list of entities to be sumbitted _deltaEntities.Clear(); // Mark any entities as unchanged that // are only sending the key Entity[] updated = GetAttachedEntities().Where(x => x.EntityState == EntityState.Changed).ToArray(); foreach (Entity target in updated) { // Ignore updates where nothing has been updated Entity unchanged = _originalEntities.Find(x => x.Id == target.Id); if (unchanged != null) { Entity cloneOfTarget = ShallowClone(target); RemoveUnchangedFields(cloneOfTarget, unchanged); _deltaEntities.Add(cloneOfTarget); // Test to see if it's only the key left... if so ignore the update otherwise you will get a blank audit record if (cloneOfTarget.Attributes.Count == 1) { object attribute = cloneOfTarget.Attributes.First().Value; var id = attribute as Guid?; if (id != null) { if (cloneOfTarget.Id == id.Value) { Detach(target); _deltaEntities.Remove(cloneOfTarget); target.EntityState = EntityState.Unchanged; Attach(target); } } } } } base.OnSavingChanges(options); }
internal BaseSaveResult(DataServiceContext context, string method, DataServiceRequest[] queries, SaveChangesOptions options, AsyncCallback callback, object state) : base(context, method, callback, state) { this.entryIndex = -1; this.RequestInfo = new System.Data.Services.Client.RequestInfo(context); this.Options = options; this.SerializerInstance = new Serializer(this.RequestInfo); if (queries == null) { this.ChangedEntries = (from o in context.EntityTracker.Entities.Cast <Descriptor>().Union <Descriptor>(context.EntityTracker.Links.Cast <Descriptor>()).Union <Descriptor>((from e in context.EntityTracker.Entities select e.StreamDescriptors).Cast <Descriptor>()) where o.IsModified && (o.ChangeOrder != uint.MaxValue) orderby o.ChangeOrder select o).ToList <Descriptor>(); foreach (Descriptor descriptor in this.ChangedEntries) { descriptor.ContentGeneratedForSave = false; descriptor.SaveResultWasProcessed = 0; descriptor.SaveError = null; if (descriptor.DescriptorKind == DescriptorKind.Link) { object target = ((LinkDescriptor)descriptor).Target; if (target != null) { Descriptor entityDescriptor = context.EntityTracker.GetEntityDescriptor(target); if (EntityStates.Unchanged == entityDescriptor.State) { entityDescriptor.ContentGeneratedForSave = false; entityDescriptor.SaveResultWasProcessed = 0; entityDescriptor.SaveError = null; } } } } } else { this.ChangedEntries = new List <Descriptor>(); } }
internal BaseSaveResult(DataServiceContext context, string method, DataServiceRequest[] queries, SaveChangesOptions options, AsyncCallback callback, object state) : base(context, method, callback, state) { this.entryIndex = -1; this.RequestInfo = new System.Data.Services.Client.RequestInfo(context); this.Options = options; this.SerializerInstance = new Serializer(this.RequestInfo); if (queries == null) { this.ChangedEntries = (from o in context.EntityTracker.Entities.Cast<Descriptor>().Union<Descriptor>(context.EntityTracker.Links.Cast<Descriptor>()).Union<Descriptor>((from e in context.EntityTracker.Entities select e.StreamDescriptors).Cast<Descriptor>()) where o.IsModified && (o.ChangeOrder != uint.MaxValue) orderby o.ChangeOrder select o).ToList<Descriptor>(); foreach (Descriptor descriptor in this.ChangedEntries) { descriptor.ContentGeneratedForSave = false; descriptor.SaveResultWasProcessed = 0; descriptor.SaveError = null; if (descriptor.DescriptorKind == DescriptorKind.Link) { object target = ((LinkDescriptor) descriptor).Target; if (target != null) { Descriptor entityDescriptor = context.EntityTracker.GetEntityDescriptor(target); if (EntityStates.Unchanged == entityDescriptor.State) { entityDescriptor.ContentGeneratedForSave = false; entityDescriptor.SaveResultWasProcessed = 0; entityDescriptor.SaveError = null; } } } } } else { this.ChangedEntries = new List<Descriptor>(); } }
public async Task CRUD(SaveChangesOptions saveChangesOptions) { var entitiesCount = await dataServiceContext.Books.EntitiesCount(); var book = new Book { Id = "Id" + RandomInt(), Title = "OData" }; dataServiceContext.AddObject(book); await dataServiceContext.SaveChangesAsync(saveChangesOptions); var refreshedBooksCount = await dataServiceContext.Books.EntitiesCount(); refreshedBooksCount.Should().Be(entitiesCount + 1, "New book was inserted to database"); string changedTitle = book.Title + " renamed"; book.Title = changedTitle; dataServiceContext.UpdateObject(book); await dataServiceContext.SaveChangesAsync(saveChangesOptions); var refreshedBook = await GetBookAsync(book.Id); refreshedBook.Should().NotBeNull("Book was saved to database"); refreshedBook.Title.Should().Be(changedTitle, "Existing book's title was updated in the database"); dataServiceContext.DeleteObject(book); await dataServiceContext.SaveChangesAsync(saveChangesOptions); refreshedBooksCount = await dataServiceContext.Books.EntitiesCount(); refreshedBooksCount.Should().Be(entitiesCount, "Existing book was deleted from database"); }
public Task<DataServiceResponse> SaveChangesWithRetriesAsync(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext) { return this.SaveChangesWithRetriesAsync(options, requestOptions, operationContext, CancellationToken.None); }
public Task<DataServiceResponse> SaveChangesWithRetriesAsync(SaveChangesOptions options, CancellationToken cancellationToken) { return AsyncExtensions.TaskFromApm(this.BeginSaveChangesWithRetries, this.EndSaveChangesWithRetries, options, cancellationToken); }
public Task<DataServiceResponse> SaveChangesWithRetriesAsync(SaveChangesOptions options) { return this.SaveChangesWithRetriesAsync(options, CancellationToken.None); }
public ICancellableAsyncResult BeginSaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) { requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); TableCommand<DataServiceResponse, DataServiceResponse> cmd = this.GenerateSaveChangesCommand(options, requestOptions); return TableExecutor.BeginExecuteAsync(cmd, requestOptions.RetryPolicy, operationContext, callback, state); }
private ExpectedClientRequest CreateEntityInsertRequest(DataServiceContextData contextData, IDictionary<object, IEnumerable<NamedValue>> propertyValuesBeforeSave, EntityDescriptorData entityDescriptorData, SaveChangesOptions options) { ExceptionUtilities.Assert(!entityDescriptorData.IsMediaLinkEntry, "Can only be used for non media-link-entries"); var insertUri = GetEntityInsertUri(contextData, entityDescriptorData); ExpectedClientRequest request = new ExpectedClientRequest() { Verb = HttpVerb.Post, Uri = insertUri }; string preference = contextData.AddAndUpdateResponsePreference.ToHeaderValue(); DataServiceProtocolVersion dsv = GetDataServiceVersion(HttpVerb.Post, preference); dsv = dsv.IncreaseVersionIfRequired(this.VersionCalculator.CalculateDataServiceVersion(entityDescriptorData, contextData.MaxProtocolVersion)); var payload = this.BuildEntityPayload(contextData, propertyValuesBeforeSave, entityDescriptorData, dsv); request.Body = payload; this.AddFoldedLinksToEntityInsertPayload(contextData, entityDescriptorData, payload); request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(dsv); request.Headers[HttpHeaders.IfMatch] = null; request.Headers[HttpHeaders.Prefer] = preference; this.SetDefaultAcceptHeader(request, options); this.SetContentTypeHeaderForEntity(request); string hintString = @"Entity insert\r\n{{\r\n Descriptor = {0}\r\n Options = {1}\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, entityDescriptorData, options); return request; }
/// <summary> /// Creates a new instance of the Serializer. /// </summary> /// <param name="requestInfo">the request info.</param> /// <param name="options">the save change options.</param> internal Serializer(RequestInfo requestInfo, SaveChangesOptions options) : this(requestInfo) { this.options = options; }
/// <summary>Saves the changes with retries implementation.</summary> /// <param name="options">The options for saving changes. </param> /// <param name="setResult">The action to set result. </param> /// <returns>A sequence of tasks to perform the operation. </returns> private TaskSequence SaveChangesWithRetriesImpl( SaveChangesOptions options, Action<DataServiceResponse> setResult) { var task = this.SaveChangesAsync(options); yield return task; setResult(task.Result); }
internal static HttpVerb GetUpdateVerb(SaveChangesOptions options) { if (options == SaveChangesOptions.ReplaceOnUpdate) { return HttpVerb.Put; } else if (options == SaveChangesOptions.PatchOnUpdate) { return HttpVerb.Patch; } else { return HttpVerb.Patch; } }
public void CreateRelatedEntitesWithDifferentChangesetOptions() { this.TestClientContext.MergeOption = MergeOption.OverwriteChanges; SaveChangesOptions[] options = new SaveChangesOptions[] { // All modifications share one changeset SaveChangesOptions.BatchWithSingleChangeset, // Each modification uses seperate changeset SaveChangesOptions.BatchWithIndependentOperations }; Airline airline = new Airline() { Name = "American Delta", AirlineCode = "DL", TimeStampValue = new byte[] { 0 } }; Flight flight = new Flight() { ConfirmationCode = "JH58496", FlightNumber = "DL589", StartsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 15, 00, 0)), EndsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 16, 30, 0)), AirlineId = "DL", SeatNumber = "C32", FromId = "KSEA", ToId = "ZSSS", Airline = airline }; foreach (var option in options) { this.TestClientContext.ResetDataSource().Execute(); // This should fail for BatchWithIndependentOperations, as the foreign key restriction breaks. this.TestClientContext.AddToFlights(flight); this.TestClientContext.AddToAirlines(airline); this.TestClientContext.SendingRequest2 += (sender, e) => { e.RequestMessage.SetHeader("Prefer", "odata.continue-on-error"); }; DataServiceResponse response1 = this.TestClientContext.SaveChanges(option); switch (option) { case SaveChangesOptions.BatchWithIndependentOperations: Assert.Equal(200, response1.BatchStatusCode); Assert.True(response1.IsBatchResponse); Assert.Equal(2, response1.Count()); var result1 = response1.ToList(); // fail for adding flight, but succeed for adding airlire Assert.Equal(500, result1[0].StatusCode); Assert.Equal(201, result1[1].StatusCode); Assert.Equal(0, this.TestClientContext .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count); break; case SaveChangesOptions.BatchWithSingleChangeset: Assert.Equal(200, response1.BatchStatusCode); Assert.True(response1.IsBatchResponse); Assert.Equal(2, response1.Count()); var result2 = response1.ToList(); // Both would succeed Assert.Equal(201, result2[0].StatusCode); Assert.Equal(201, result2[1].StatusCode); Assert.Equal(1, this.TestClientContext .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count); break; } this.TestClientContext.Detach(airline); this.TestClientContext.Detach(flight); } }
private ExpectedClientRequest CreateStreamUpdateRequest(StreamDescriptorData streamDescriptorData, SaveChangesOptions options) { var request = this.CreateSaveStreamRequest(streamDescriptorData, streamDescriptorData.EditLink); request.Headers[HttpHeaders.IfMatch] = streamDescriptorData.ETag; request.Headers[HttpHeaders.Prefer] = null; request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(DataServiceProtocolVersion.V4); this.SetDefaultAcceptHeader(request, options); SetContentTypeHeaderForStream(request, streamDescriptorData); string hintString = @"Stream update\r\n{{\r\n Descriptor = {0}\r\n\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, streamDescriptorData); return request; }
private ExpectedClientRequest CreateStreamInsertRequest(DataServiceContextData contextData, StreamDescriptorData streamDescriptorData, SaveChangesOptions options) { ExceptionUtilities.Assert(streamDescriptorData.Name == null, "Can only be used for media-resources"); var insertUri = GetEntityInsertUri(contextData, streamDescriptorData.EntityDescriptor); var request = this.CreateSaveStreamRequest(streamDescriptorData, insertUri); string preference = contextData.AddAndUpdateResponsePreference.ToHeaderValue(); var dsv = GetDataServiceVersion(request.Verb, preference); request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(dsv); request.Headers[HttpHeaders.IfMatch] = null; request.Headers[HttpHeaders.Prefer] = preference; this.SetDefaultAcceptHeader(request, options); SetContentTypeHeaderForStream(request, streamDescriptorData); string hintString = @"Stream insert\r\n{{\r\n Descriptor = {0}\r\n\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, streamDescriptorData); return request; }
private ExpectedClientRequest CreateEntityUpdateRequest(DataServiceContextData contextData, IDictionary<object, IEnumerable<NamedValue>> propertyValuesBeforeSave, EntityDescriptorData entityDescriptorData, SaveChangesOptions options) { var request = new ExpectedClientRequest() { Verb = GetUpdateVerb(options), Uri = entityDescriptorData.EditLink, }; string preference = contextData.AddAndUpdateResponsePreference.ToHeaderValue(); var dsv = GetDataServiceVersion(request.Verb, preference); dsv = dsv.IncreaseVersionIfRequired(this.VersionCalculator.CalculateDataServiceVersion(entityDescriptorData, contextData.MaxProtocolVersion)); request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(dsv); request.Headers[HttpHeaders.IfMatch] = entityDescriptorData.ETag; request.Headers[HttpHeaders.Prefer] = preference; this.SetDefaultAcceptHeader(request, options); this.SetContentTypeHeaderForEntity(request); request.Body = this.BuildEntityPayload(contextData, propertyValuesBeforeSave, entityDescriptorData, dsv); string hintString = @"Entity update\r\n{{\r\n Descriptor = {0}\r\n Options = {1}\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, entityDescriptorData, options); return request; }
private ExpectedClientRequest CreateEntityDeleteRequest(EntityDescriptorData entityDescriptorData, SaveChangesOptions options) { var request = new ExpectedClientRequest() { Verb = HttpVerb.Delete, Uri = entityDescriptorData.EditLink, }; request.Headers[HttpHeaders.IfMatch] = entityDescriptorData.ETag; request.Headers[HttpHeaders.Prefer] = null; request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(DataServiceProtocolVersion.V4); this.SetDefaultAcceptHeader(request, options); request.Headers[HttpHeaders.ContentType] = null; string hintString = @"Entity delete\r\n{{\r\n Descriptor = {0}\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, entityDescriptorData); return request; }
public Task<DataServiceResponse> SaveChangesWithRetriesAsync(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) { return AsyncExtensions.TaskFromApm(this.BeginSaveChangesWithRetries, this.EndSaveChangesWithRetries, options, requestOptions, operationContext, cancellationToken); }
internal TableCommand<DataServiceResponse, DataServiceResponse> GenerateSaveChangesCommand(SaveChangesOptions options, TableRequestOptions requestOptions) { TableCommand<DataServiceResponse, DataServiceResponse> cmd = new TableCommand<DataServiceResponse, DataServiceResponse>(); if (requestOptions.ServerTimeout.HasValue) { this.Timeout = (int)requestOptions.ServerTimeout.Value.TotalSeconds; } cmd.ExecuteFunc = () => this.SaveChanges(options); cmd.Begin = (callback, state) => this.BeginSaveChanges(options, callback, state); cmd.End = this.EndSaveChanges; cmd.ParseResponse = this.ParseDataServiceResponse; cmd.ParseDataServiceError = StorageExtendedErrorInformation.ReadDataServiceResponseFromStream; cmd.Context = this; requestOptions.ApplyToStorageCommand(cmd); return cmd; }
/// <summary> /// Calculates expected data for a request during DataServiceContext.SaveChanges for a particular descriptor. /// </summary> /// <param name="contextData">The context data</param> /// <param name="propertyValuesBeforeSave">The property values of the tracked client objects before the call to SaveChanges</param> /// <param name="descriptorData">The descriptor data</param> /// <param name="options">The save changes options</param> /// <returns>The expected client request</returns> public ExpectedClientRequest CalculateRequest(DataServiceContextData contextData, IDictionary<object, IEnumerable<NamedValue>> propertyValuesBeforeSave, DescriptorData descriptorData, SaveChangesOptions options) { ExceptionUtilities.CheckArgumentNotNull(contextData, "contextData"); ExceptionUtilities.CheckArgumentNotNull(descriptorData, "descriptorData"); ExceptionUtilities.CheckArgumentNotNull(propertyValuesBeforeSave, "propertyValuesBeforeSave"); var linkDescriptorData = descriptorData as LinkDescriptorData; var entityDescriptorData = descriptorData as EntityDescriptorData; var streamDescriptorData = descriptorData as StreamDescriptorData; ExpectedClientRequest request = null; if (linkDescriptorData != null) { if (linkDescriptorData.WillTriggerSeparateRequest()) { request = this.CreateLinkRequest(linkDescriptorData, options); } } else if (entityDescriptorData != null) { if (entityDescriptorData.State == EntityStates.Added) { request = this.CreateEntityInsertRequest(contextData, propertyValuesBeforeSave, entityDescriptorData, options); } else if (entityDescriptorData.State == EntityStates.Modified) { request = this.CreateEntityUpdateRequest(contextData, propertyValuesBeforeSave, entityDescriptorData, options); } else if (entityDescriptorData.State == EntityStates.Deleted) { request = this.CreateEntityDeleteRequest(entityDescriptorData, options); } } else if (streamDescriptorData != null) { if (streamDescriptorData.State == EntityStates.Added) { request = this.CreateStreamInsertRequest(contextData, streamDescriptorData, options); } else if (streamDescriptorData.State == EntityStates.Modified) { request = this.CreateStreamUpdateRequest(streamDescriptorData, options); } } if (request != null) { request.Headers[HttpHeaders.MaxDataServiceVersion] = ToClientHeaderFormat(contextData.MaxProtocolVersion); // perform sanity checks var missingHeaders = headersThatWillBeGenerated.Where(h => !request.Headers.ContainsKey(h)).ToArray(); ExceptionUtilities.Assert(missingHeaders.Length == 0, "Generated request was missing headers: {0}", string.Join(", ", missingHeaders)); ExceptionUtilities.CheckObjectNotNull(request.Uri, "Generated request was missing a Uri"); // sanity check: Client sends content-type header for delete request if (request.GetEffectiveVerb() == HttpVerb.Delete) { ExceptionUtilities.Assert( request.Headers[HttpHeaders.ContentType] == null, "Incorrect expectation: client should never send ContentType header for DELETE requests."); } } return request; }
public DataServiceResponse SaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions = null, OperationContext operationContext = null) { requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); TableCommand<DataServiceResponse, DataServiceResponse> cmd = this.GenerateSaveChangesCommand(options, requestOptions); return TableExecutor.ExecuteSync(cmd, requestOptions.RetryPolicy, operationContext); }
public ICancellableAsyncResult BeginSaveChangesWithRetries(SaveChangesOptions options, AsyncCallback callback, object state) { return this.BeginSaveChangesWithRetries(options, null /* RequestOptions */, null /* OperationContext */, callback, state); }
private ExpectedClientRequest CreateLinkRequest(LinkDescriptorData linkDescriptorData, SaveChangesOptions options) { var info = linkDescriptorData.SourceDescriptor.LinkInfos.SingleOrDefault(l => l.Name == linkDescriptorData.SourcePropertyName); ExpectedClientRequest request = new ExpectedClientRequest() { Uri = BuildLinkUri(linkDescriptorData, info) }; if (linkDescriptorData.State == EntityStates.Added) { request.Verb = HttpVerb.Post; // note: the edit-link is used rather than identity because the server needs to be able to query for the target entity // and the identity may not be an actual uri request.Body = new DeferredLink() { UriString = linkDescriptorData.TargetDescriptor.EditLink.OriginalString }; } else if (linkDescriptorData.State == EntityStates.Modified) { if (linkDescriptorData.TargetDescriptor == null) { request.Verb = HttpVerb.Delete; } else { request.Verb = HttpVerb.Put; // note: the edit-link is used rather than identity because the server needs to be able to query for the target entity // and the identity may not be an actual uri request.Body = new DeferredLink() { UriString = linkDescriptorData.TargetDescriptor.EditLink.OriginalString }; } } else { ExceptionUtilities.Assert(linkDescriptorData.State == EntityStates.Deleted, "Link descriptor was in unexpected state '{0}'", linkDescriptorData.State); string keyString = this.EntityDescriptorValueCalculator.CalculateEntityKey(linkDescriptorData.TargetDescriptor.Entity); request.Uri = new Uri(request.Uri.OriginalString + keyString); request.Verb = HttpVerb.Delete; } request.Headers[HttpHeaders.IfMatch] = null; request.Headers[HttpHeaders.Prefer] = null; request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(DataServiceProtocolVersion.V4); this.SetDefaultAcceptHeader(request, options); if (request.Verb != HttpVerb.Delete) { request.Headers[HttpHeaders.ContentType] = string.IsNullOrWhiteSpace(this.ClientRequestAcceptHeader) ? MimeTypes.ApplicationXml : this.ClientRequestAcceptHeader; } else { request.Headers[HttpHeaders.ContentType] = null; } string hintString = @"Link\r\n{{\r\n Descriptor = {0}\r\n Options = {1}\r\n}}"; request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, linkDescriptorData, options); return request; }
/// <summary> /// Saves changes, using the retry policy specified for the service context. /// </summary> /// <param name="options">Additional options for saving changes.</param> /// <returns> A <see cref="DataServiceResponse"/> that represents the result of the operation.</returns> public DataServiceResponse SaveChangesWithRetries(SaveChangesOptions options) { return(TaskImplHelper.ExecuteImplWithRetry <DataServiceResponse>( (setResult) => this.SaveChangesWithRetriesImpl(options, setResult), RetryPolicy)); }
/// <summary>Begins an asynchronous operation to save changes, using the retry policy specified for the service context.</summary> /// <param name="options">Additional options for saving changes. </param> /// <param name="callback">The callback delegate that will receive notification when the asynchronous operation completes. </param> /// <param name="state">A user-defined object that will be passed to the callback delegate. </param> /// <returns>An <see cref="IAsyncResult"/> that references the asynchronous operation. </returns> public IAsyncResult BeginSaveChangesWithRetries( SaveChangesOptions options, AsyncCallback callback, object state) { return TaskImplHelper.BeginImplWithRetry<DataServiceResponse>( setResult => this.SaveChangesWithRetriesImpl(options, setResult), this.RetryPolicy, callback, state); }
/// <summary>Saves changes, using the retry policy specified for the service context.</summary> /// <param name="options">Additional options for saving changes. </param> /// <returns>A <see cref="DataServiceResponse"/> that represents the result of the operation. </returns> public DataServiceResponse SaveChangesWithRetries(SaveChangesOptions options) { return TaskImplHelper.ExecuteImplWithRetry<DataServiceResponse>( setResult => this.SaveChangesWithRetriesImpl(options, setResult), this.RetryPolicy); }