locked
Getting Errors out of a ModelMembersBulkUpdate RRS feed

  • General discussion

  • Hi there,

    the documentation to ModelMembersBulkUpdate describes: "The operation returns the batch ID for the staging records, not the results of the update."

    So what is the best way to get errors occuring in the process of updating members?

    I have a solution but frankly I`m not quite satifies with it. Out of the ModelMembersBulkUpdateResponse I extract die Ids of the batch that IS shifting data from staging to the related tables during ModelMembersBulkUpdate.

    I spelled IS in uppercase letters because there IS a chance that the batch is still queued or running so a while() has to do the job. I call the StageGet till the batch is finished.

    So my question is: is there a better way to get the errors out of ModelMembersBulkUpdate?

     ModelMembersBulkUpdateRequest request = new ModelMembersBulkUpdateRequest(international, lstEntityMembers);
    
          //Obwohl die Klasse ModelMembersBulkUpdateResponse ein OperationResult definiert wird dieses nicht sauber mit den aufgetretenen Fehlern 
          //gefüllt. Die Fehler kommen aus dem zugehörigen Batch siehe unten
          ModelMembersBulkUpdateResponse response = new ModelMembersBulkUpdateResponse();
          response = proxy.ModelMembersBulkUpdate(request);
    
          StagingGetRequest stagingGetRequest = new StagingGetRequest();
          stagingGetRequest.IncludeUnbatchedInformation = false;
          stagingGetRequest.International = international;
          stagingGetRequest.StagingResultCriteria = new StagingResultCriteria() { Attributes = true, Members = true, All = true };
          stagingGetRequest.StagingSearchCriteria = new StagingSearchCriteria() { StagingBatches = new Collection<Identifier>() { new Identifier() { Id = response.StagingBatches[0].Id, InternalId = response.StagingBatches[0].InternalId } } };
          StagingGetResponse stagingGetResponse = proxy.StagingGet(stagingGetRequest);
    
    
          // Da der Batch nicht erst dann wenn er fertig ist von StagingGet geliefert wird muss hier in einer Schleife der Batch so lange 
          // angefragt werden bis sein Status nicht mehr auf Running oder QueuedToRun steht.- Denn erst dann können die Errors, die beim Batchen 
          // enstanden sind ausgewertet werden
          // Achtung nicht alles Errors, die einen Errorcode in den ErrorCode Spalten eintragen werden hier mit geführt
          // dabei handelt es sich um Datensätze mit der Status_ID=2 2, which is automatically assigned and indicates that staging for the record has failed.
          var status = stagingGetResponse.Batches[0].Information.Status;
          while (status == StagingBatchStatus.Running || status == StagingBatchStatus.QueuedToRun)
          {
            stagingGetResponse = proxy.StagingGet(stagingGetRequest);
            status = stagingGetResponse.Batches[0].Information.Status;
    
          }
    
          List<string> errorList = new List<string>();
          foreach (StagingBatchError error in stagingGetResponse.Batches[0].Errors)
          {
           //do something
          }
    

     

    Tuesday, March 15, 2011 4:52 PM

All replies

  • Hi

    did you try to use Merge instead of update (the difference is : update will throw an error if code already exist, but merge will update item if code already exists)

    please check this link

    http://xavieraverbouch.blogspot.com/2011/03/sql-2008-r2-master-data-services-bulk.html

    in order to get error codes, I use "Operation Result" Errors

    Regards,

     



    Xavier Averbouch
    Avanade , FRANCE
    If a post answers your question, please click "Mark As Answer" on that post and "Vote as Helpful".
    Tuesday, March 15, 2011 5:47 PM
  • Hi Xavier,

    what do you mean with: "if code already exist"?

    By the way even ModelMembersBulkMerge is documented as following:

    The operation returns the batch IDs for the staging records, not the results of the Create or Update operation

    So how to get the errors if the OperationResult does not keep them.

    It makes sense, because the result gets back to my application before the batch is done.

    Rouven

    Wednesday, March 16, 2011 8:32 AM
  • Hi Rouven

    sorry for my mistake :

    I made a confusion between ModelMembersBulkUpdate and EntityMembersCreate !

    EntityMembersCreate : only new member records with unique codes can be created with this operation. If a member code already exists, an error will be thrown in the returned error collection and the member will not be created or updated.

    EntityMembersMerge : Many users have been confused by this operation and believe it has something to do with record survivorship or match merge functionality. This operation does nothing to look for possible matches or provide any survivorship functionality; it only allows users to create and update records simultaneously within MDS.

    In fact, you can get the error codes on MDS website : in "Integration Management/Staging Batches" clicking on the batch you want and clicking on button "view details for selected batch"

    in order to do the same thing with API (get error codes), you'll need to get back the batch after it is inserted. 


     

    //get information related to a staging batch
     public Collection<StagingBatch> StagingGet(Collection<Identifier> stagingBatch, bool ReturnAllCriteria, bool ReturnMembers, bool ReturnAttributes, bool ReturnRelationShips, ref OperationResult or)
     {
     Collection<StagingUnbatchedInformation> colUnbatched = new Collection<StagingUnbatchedInformation>();
     Collection<StagingBatch> colBatches = new Collection<StagingBatch>();
     using (ServiceClient c = MDS_WSConnect.CreateMdsProxy())
     {
     or = new OperationResult();
     colBatches = c.StagingGet(new International(), true, new StagingResultCriteria() { All = ReturnAllCriteria, Attributes = ReturnAttributes, Members = ReturnMembers, Relationships = ReturnRelationShips },
     new StagingSearchCriteria() { StagingBatches = stagingBatch, StagingDataStatus= StagingDataStatus.All }, out or, out colUnbatched);
     List<string> lstErr = new List<string>();
    
     //...do what you need with the error collection
    
    foreach (<strong>StagingBatchError err in colBatches.First().Errors</strong>)
    
     {
     lstErr.Add(err.ErrorCode + " - " + err.TargetCode);
     }
    
     return colBatches;
     }
     }
    

    so, complete process would be:

     

     DateTime dtBefore = DateTime.Now; 
    OperationResult or = new OperationResult();
      //filling new staging batch with entityMembers
      Collection<Identifier> colStaging = ModelMembersBulkMerge(colEntMembers);
      //initiating the staging process (not sure I really need that here in fact)
      Collection<StagingBatch> colBatches = StagingGet(colStaging, true, true, true, false, ref or);
      //triggering staging
      ProcessUnbatchedStaging(pModelId, pVersionId);
    
      DateTime dtAfter = DateTime.Now;
      TimeSpan ts = dtAfter.Subtract(dtBefore);
    
      MessageBox.Show("members (bulk) inserted : " + colEntMembers.First().Members.Count() + "\r\n" + "time elapsed (seconds):" + ts.TotalSeconds.ToString());
      //get back the batch to see if any errors 
      
      colBatches = StagingGet(colStaging, true, true, true, false, ref or);

    note: StagingDataStatus= StagingDataStatus.All --> get all including Errors

    Regards,

     



    Xavier Averbouch
    Avanade , FRANCE
    If a post answers your question, please click "Mark As Answer" on that post and "Vote as Helpful".
    Wednesday, March 16, 2011 11:14 AM
  • Hi Xavier,

    thanks a lot for the posted answer. Please read my initial post in this thread. Getting the errors over the StagingBatch is exactely what I did. The only question remaining is: how can you be sure that the batch has already passed stauts "QueuedTorRun" or "Running" at the time you call StagingGet()?

    The only way I figured out to accomplish this is to do a while loop:

     while (status == StagingBatchStatus.Running || status == StagingBatchStatus.QueuedToRun)
       {
        stagingGetResponse = proxy.StagingGet(stagingGetRequest);
        status = stagingGetResponse.Batches[0].Information.Status;
    
       }
    
    

    Cu

    Rouven

    Wednesday, March 16, 2011 11:50 AM
  • Hi Rouven

    I don't see neither a better way for now...

    Regards,



    Xavier Averbouch
    Avanade , FRANCE
    If a post answers your question, please click "Mark As Answer" on that post and "Vote as Helpful".
    Wednesday, March 16, 2011 12:16 PM