Question

Problem when modifying an existing object (WCF / oData)

We are currently working on a project that uses the OData protocol with WCF and, even though it's using the exactly same structure of the example from the academy, we are facing some problems when trying to update an object.

Code:

// Creating the context of the BPMonline application.
BPMonline context = new BPMonline(serverUri);
// Determining the method which adds authentication cookie when creating a new request.
context.SendingRequest += new EventHandler<SendingRequestEventArgs>(OnSendingRequestCookie);
// The account on which basis the data will be modified is selected from the accounts collection.
var updateAccount = context.AccountCollection.Where(a => a.Name.Contains("Praxi Solutions do Brasil")).First();
// Modifying the selected account properties.
updateAccount.Web = "www.test.com";
// Saving the modifications in the service data model.
context.UpdateObject(updateAccount);
// Saving the modification of data in BPMonline by one request.
var responces = context.SaveChanges(SaveChangesOptions.Batch);

 

Error:

?xml version="1.0" encoding="utf-8"?>
m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  m:code>2/m:code>
  m:message xml:lang="">The UPDATE statement conflicted with the FOREIGN KEY SAME TABLE constraint "FKvY8UYv12vEuVbKnUeMUSZ4IYo". The conflict occurred in database "0412571-sales-enterprise-marketing-service-enterprise-demo", table "dbo.Account", column 'Id'.The statement has been terminated./m:message>
  m:innererror>
    m:message>The UPDATE statement conflicted with the FOREIGN KEY SAME TABLE constraint "FKvY8UYv12vEuVbKnUeMUSZ4IYo". The conflict occurred in database "0412571-sales-enterprise-marketing-service-enterprise-demo", table "dbo.Account", column 'Id'.The statement has been terminated./m:message>
    m:type>Terrasoft.Common.DbOperationException/m:type>
    m:stacktrace>   at Terrasoft.Core.Entities.Services.ServiceContext.SaveChanges()   at System.Data.Services.DataService`1.BatchDataService.HandleBatchContent(Stream responseStream)/m:stacktrace>
    m:internalexception>
      m:message>The UPDATE statement conflicted with the FOREIGN KEY SAME TABLE constraint "FKvY8UYv12vEuVbKnUeMUSZ4IYo". The conflict occurred in database "0412571-sales-enterprise-marketing-service-enterprise-demo", table "dbo.Account", column 'Id'.The statement has been terminated./m:message>
      m:type>System.Data.SqlClient.SqlException/m:type>
      m:stacktrace>   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean dataReady)   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption)   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task task, Boolean usedCache, Boolean asyncWrite, Boolean inRetry)   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean usedCache, Boolean asyncWrite, Boolean inRetry)   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()   at Terrasoft.Core.DB.DBExecutor.FailoverExecute[TResult](DbCommand command, Func`1 func)   at Terrasoft.Core.DB.DBExecutor.Execute(String sqlText, QueryParameterCollection parameters)   at Terrasoft.Core.DB.Query.Execute()   at Terrasoft.Core.Entities.Entity.ExecuteUpdate(Update update, Update parentUpdate)   at Terrasoft.Core.Entities.Entity.UpdateInDB(Boolean validateRequired)/m:stacktrace>
    /m:internalexception>
  /m:innererror>
/m:error>

 

We used the Account object for this example, because we didn't do any customization on it. All the other examples (select, insert and delete) worked perfectly.

Does anyone know how to solve this problem?

File attachments

Like

1 comments

I don't recommend using WCF. It's much better to use http requests.

According your question, most likely that the issue happened due the fact that when you update the "web" field in the account object, the WCF object actually updates all of the fields in the account. If one of the lookup fields in the account was empty, the WCF request will try to update it with Guid.Empty value. This action will generate an error.

You can run fiddler and catch the request that you send. You will see that WCF tryes to update much more than you specified. 

You will not face such an error with http requests. I recommend to use them.

Show all comments