# WCF Update of CustCnt throws exception **Category:** [Epicor ERP 10](https://www.epiusers.help/c/e10/5) **Created:** 2016-10-31 17:24 UTC **Views:** 1761 **Replies:** 5 **URL:** https://www.epiusers.help/t/wcf-update-of-custcnt-throws-exception/36025 --- ## Post #1 by @tvonderhaar I have been testing WCF in E10 and have working code against the Customer service, but similar code against the CustCnt service throws and exception. Using a simple test example, I retrieve rows for a customer, look through looking for a last name, update the First Name, set RowMod to "U" and then perform an Update. ```cs var custcnt = new CustCntTableset(); custcnt = cuscntclient.GetRows(out morePages, “CustNum = 5219”, “”, 0, 1); foreach (CustCntRow cnt in custcnt.CustCnt) { If (cnt.LastName == “VonDerHaar”) { Cnt.FirstName = “Test”; Cnt.RowMod = “U”; } Custcntclient.Update(ref custcnt); } ``` An exception is raised when the Update is attempted: System.Data.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'PK_CustCnAttr'. Cannot insert duplicate key in object 'Erp.CustCnAttr'. The duplicate key value is (FCII01, 5219, , 1, ). The statement has been terminated. 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.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior) at Epicor.Data.Provider.EpiCommand.ExecuteDbDataReader(CommandBehavior behavior) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Data\EpiProvider2\EpiCommand.cs:line 274 at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues) at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) --- End of inner exception stack trace --- at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at Ice.IceDataContext.SaveChanges(SaveOptions options) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Data\IceDataContext.cs:line 328 at Ice.IceDataContext.Validate[TLinqRow](TLinqRow row) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Data\IceDataContext.cs:line 295 at Erp.Services.BO.CustCntSvc.updateAttributes() in c:\_Releases\ERP\RL10.1.400.0\Source\Server\Services\BO\CustCnt\CustCnt.cs:line 1657 at Erp.Services.BO.CustCntSvc.CustCntBeforeUpdate() in c:\_Releases\ERP\RL10.1.400.0\Source\Server\Services\BO\CustCnt\CustCnt.cs:line 884 at Ice.Services.Trace.TablesetProfilingCollector.DoRowEventTrace(String tableName, String methodName, Int32 rowCount, Action action) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.Ice\Services\TablesetProfilingCollector.cs:line 144 at Ice.TablesetBound`3.UpdateRow(IceDataContext dataContext, Int32 tableNum, IIceTable table, IceRow updatedRow, IceRow originalRow, TablesetProfilingCollector parentTraceCollector) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.Ice\Services\TablesetBound.cs:line 1155 at Ice.TablesetBound`3.WriteTable(IceDataContext dataContext, Int32 tableIndex, IIceTable table, TablesetProfilingCollector parentTraceCollector) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.Ice\Services\TablesetBound.cs:line 894 at Ice.TablesetBound`3.InnerUpdate(IceDataContext dataContext, TFullTableset tableset) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.Ice\Services\TablesetBound.cs:line 796 at Erp.Services.BO.CustCntSvc.Update(CustCntTableset& ds) in c:\_Releases\ERP\RL10.1.400.0\Source\Server\Services\BO\CustCnt\CustCnt.Designer.cs:line 848 at Epicor.Customization.Bpm.MethodCustomizationBase2`3.RunDirectives(TParam parameters) in c:\_Releases\ICE\3.1.400.10\source\Server\Internal\Lib\Epicor.Customization.BPM\MethodCustomizationBase2.cs:line 218 at Epicor.Customization.Bpm.CustomizationBase2`3.Execute(TParam parameters) in c:\_Releases\ICE\3.1.400.10\source\Server\Internal\Lib\Epicor.Customization.BPM\CustomizationBase2.cs:line 77 at Epicor.Customization.Bpm.BO177D37D68398474098FA410429D05638.CustCntSvcCustomization.Update(CustCntTableset& ds) at Erp.Services.BO.CustCntSvcFacade.Update(CustCntTableset& ds) in c:\_Releases\ERP\RL10.1.400.0\Source\Server\Services\BO\CustCnt\CustCntSvcFacade.cs:line 213 at SyncInvokeUpdate(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at Epicor.Hosting.OperationBoundInvoker.InnerInvoke(Object instance, Func`2 func) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 59 at Epicor.Hosting.OperationBoundInvoker.Invoke(Object instance, Func`2 func) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 28 Any ideas? Tim --- ## Post #2 by @josecgomez Are you using the WCF Services outside of Epicor? If so you may need to clone the Record in order for the Update to work correctly. Note this will "break" your for each loop so you may have to move to a for loop or some other mechanism. ```cs if (cnt.LastName == “VonDerHaar”) { CustCntRow backUpRow = new CustCntRow(); var fields = backUpRow.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach(var field in fields) { if (field.PropertyType == typeof(System.Runtime.Serialization.ExtensionDataObject)) continue; var fieldValue = field.GetValue(cnt); field.SetValue(backUpRow, fieldValue); } custcnt.CustCnt.Add(backUpRow); Cnt.FirstName = “Test”; Cnt.RowMod = “U”; Custcntclient.Update(ref custcnt); } ``` --- ## Post #3 by @tvonderhaar Curious. I am using the services outside of Epicor so I guess this would apply, but why would things act differently with the CustCnt service than it did with the Customer service? Also feels and looks strange to have to do a .Add when it's really an update. --- ## Post #4 by @josecgomez ITs not an add, you are adding a a row to the data set to let it know what the previous version was (ttPrev, vs ttPost) some BO's work without it. Give it a shot and see --- ## Post #5 by @tvonderhaar Seems to do the trick. Very grateful for your help. Crazy that all BOs don't work the same. --- ## Post #6 by @josecgomez Technically you should do that for every BO. See coming from 9 you used to have a before and a changed record. In order to use BPMs with conditions such as field z change from x to y --- **Canonical:** https://www.epiusers.help/t/wcf-update-of-custcnt-throws-exception/36025 **Original content:** https://www.epiusers.help/t/wcf-update-of-custcnt-throws-exception/36025