2016-04-08 13 views
0

Ich habe ein Szenario in CRM, wo ich bestehende Konten mit ihrer Mehrwertsteuer und Registrierungsnummer aktualisieren muss. Es gibt weit über 30 Tausend Konten im System. Ich versuche, mit der CRM SDK-API zu aktualisieren, aber ich kämpfe, um herauszufinden, wie das eigentliche Update durchgeführt wird. Die Umsatzsteueridentifikationsnummer und -registrierung wurden mir in einer Tabelle mit der entsprechenden Nummer zur Verfügung gestellt. Bitte beachten Sie, dass die Konten bereits in CRM enthalten sind. Daher muss nur das korrekte Konto mit der Umsatzsteuer- und Registrierungsnummer aktualisiert werden Bitte beachten Sie meinen Code unten:CRM Dynamics 2013 SDK Aktuelle Konten mit 2 Werten aktualisieren

public static void UpdateAllCRMAccountsWithVATAndRegistrationNumber(IOrganizationService service) 
     { 
      QueryExpression qe = new QueryExpression(); 
      qe.EntityName = "account"; 
      qe.ColumnSet = new ColumnSet("account", "new_vatno", "new_registrationnumber"); 
      qe.Criteria.AddCondition("accountnumber", ConditionOperator.In,"TA10024846", "TA10028471", "TA20014015", "TA4011652", "TA4011557"); 

      EntityCollection response = service.RetrieveMultiple(qe); 

      foreach (var acc in response.Entities) 
      { 
       acc.Attributes["new_vatno"] = //this is where I am struggling to figure out how I am gong to match the records up, 
       acc.Attributes["new_registrationnumber"] = //this is where I am struggling to figure out how I am gong to match the records up, 

       service.Update(acc); 
      } 


     } 

Wie werde ich sicherstellen, dass ich die richtigen Datensätze aktualisieren. Ich habe die Mehrwertsteuer- und Registrierungsnummern für die Konten in einer Tabelle, siehe Beispielbild unten. Kann ich bitte hier beraten werden? Vielen Dank.

SpreadSheet With Accounts with the vat numbers and registration numbers

Antwort

0

Ich würde die Liste des MwSt-Updates aus der Tabelle in ein Wörterbuch laden und dann die 30k Datensatz aus CRM in den Speicher laden. Dann würde ich sie zusammenbringen und ExecuteMultipleRequest verwenden, um die Aktualisierungen vorzunehmen. Alternativ können Sie CRM unter Verwendung der Kontonummern abfragen (wenn die Liste klein genug ist). Ich machte die Annahme, dass Sie tausende von Aktualisierungen für den Datensatz von 30k durchführen mussten. Hinweis: Wenn die Account Datensatzgröße sehr groß ist und nicht in den Arbeitsspeicher geladen werden kann, müssen Sie Kontonummernabfragen durchführen. Hier

ist der grobe Code für die Basislösung (habe ich nicht getestet, Verfahren aufgeteilt werden sollen, und es gibt eine minimale Fehlerbehandlung):

public class VatInfo 
{ 
    public string RegistrationNumber; 
    public string TaxNumber; 

    public static Dictionary<string, VatInfo> GetVatList() 
    { 
     //TODO: Implement logic to load CSV file into a list. Dictionary key value should be Account Number   
     throw new NotImplementedException(); 
    } 
} 


public class UpdateVatDemo 
{ 
    public const int maxBatchSize = 100; 

    public static void RunVatUpdate(IOrganizationService conn) 
    { 

     var vats = VatInfo.GetVatList(); 

     var pagingQuery = new QueryExpression("account"); 
     pagingQuery.ColumnSet = new ColumnSet("accountnumber"); 

     Queue<Entity> allEnts = new Queue<Entity>(); 

     while (true) 
     { 

      var results = conn.RetrieveMultiple(pagingQuery); 

      if (results.Entities != null && results.Entities.Any()) 
       results.Entities.ToList().ForEach(allEnts.Enqueue); 

      if (!results.MoreRecords) break; 

      pagingQuery.PageInfo.PageNumber++; 
      pagingQuery.PageInfo.PagingCookie = results.PagingCookie; 

     } 

     ExecuteMultipleRequest emr = null; 

     while (allEnts.Any()) 
     { 
      if (emr == null) 
       emr = new ExecuteMultipleRequest() 
       { 
        Settings = new ExecuteMultipleSettings() 
        { 
         ContinueOnError = true, 
         ReturnResponses = true 
        }, 
        Requests = new OrganizationRequestCollection() 
       }; 

      var ent = allEnts.Dequeue(); 

      if (vats.ContainsKey(ent.GetAttributeValue<string>("accountnumber"))) 
      { 
       var newEnt = new Entity("account", ent.Id); 
       newEnt.Attributes.Add("new_vatno", vats[ent.GetAttributeValue<string>("accountnumber")].TaxNumber); 
       newEnt.Attributes.Add("new_registrationnumber", vats[ent.GetAttributeValue<string>("accountnumber")].RegistrationNumber); 
       emr.Requests.Add(new UpdateRequest() { Target = newEnt }); 
      } 


      if (emr.Requests.Count >= maxBatchSize) 
      { 
       try 
       { 
        var emResponse = (ExecuteMultipleResponse) conn.Execute(emr); 

        foreach (
         var responseItem in emResponse.Responses.Where(responseItem => responseItem.Fault != null)) 
         DisplayFault(emr.Requests[responseItem.RequestIndex], 
          responseItem.RequestIndex, responseItem.Fault); 

       } 
       catch (Exception ex) 
       { 
        Console.WriteLine($"Exception during ExecuteMultiple: {ex.Message}"); 
        throw; 
       } 

       emr = null; 
      } 


     } 

    } 

    private static void DisplayFault(OrganizationRequest organizationRequest, int count, 
     OrganizationServiceFault organizationServiceFault) 
    { 
     Console.WriteLine(
      "A fault occurred when processing {1} request, at index {0} in the request collection with a fault message: {2}", 
      count + 1, 
      organizationRequest.RequestName, 
      organizationServiceFault.Message); 
    } 

} 
+0

Dank @Nicknow, ich habe es geschaffen, es richtig zu machen einen etwas anderen Ansatz. Siehe meine Antwort unten. – Papi

+0

@papi - deine Antwort ist falsch, es ist schlechter Code, der nicht kompiliert wird und nicht tun würde, was du sagst. Jeder, der deine Antwort als richtig erachtet, ist irregeleitet. Selbst wenn es kompiliert wurde, ist es nicht empfehlenswert, das ursprüngliche Entitätsobjekt im Aktualisierungsaufruf an den CRM-Server zu senden. Sie müssen lediglich die ID und die fehlerhaften Felder senden. Außerdem wäre Ihr Code furchtbar ineffizient. – Nicknow

+0

Danke für die konstruktive Kritik. Ich werde den vorgeschlagenen Ansatz versuchen. – Papi

0

die abgerufenen Einheit aktualisiert wird gebunden, weil zum Scheitern verurteilt von seinem Entitätszustand, der nicht null wäre.

die abgerufenen Entitäten zu aktualisieren, müssen Sie neu bis zur Einheit:

foreach (var acc in response.Entities) 
     { 
      var updateAccount = new Entity("account") { Id = acc.Id }; 
      updateAccount .Attributes["new_vatno"] = null; //using null as an example. 
      updateAccount .Attributes["new_registrationnumber"] = null; 
      service.Update(acc); 
     } 
-1

-Code unten zeigt, wie ich es righy bekommen verwaltet. Jetzt lass mich das erklären. Ich habe meine Datensätze in eine separate SQL-Tabelle importiert, in meinem Code habe ich diese Tabelle in eine Liste im Speicher gelesen, dann CRM-Konten abgefragt, die aktualisiert werden müssen, dann wiederhole ich jedes Konto und überprüfe, ob die Kontonummer in CRM übereinstimmt Kontonummer aus der Liste meiner sQL-Datenbank, wenn sie paßt, ich aktualisiere dann die entsprechenden Reg.-Nr. und Vat nein, siehe Code unten:

List<Sheet1_> crmAccountList = new List<Sheet1_>(); 

      //var crmAccount = db.Sheet1_.Select(x => x).ToList().Take(2); 
      var crmAccounts = db.Sheet1_.Select(x => x).ToList(); 


      foreach (var dbAccount in crmAccounts) 
      { 
       CRMDataObject modelObject = new CRMDataObject() 
       { 
        ID = dbAccount.ID, 
        Account_No = dbAccount.Account_No, 
        Tax_No = dbAccount.Tax_No.ToString(), 
        Reg_No = dbAccount.Reg_No 
        //Tarsus_Country = dbAccount.Main_Phone 
       }; 

      } 

      var officialDatabaseList = crmAccounts; 

      foreach (var crmAcc in officialDatabaseList) 
      { 
       QueryExpression qe = new QueryExpression(); 
       qe.EntityName = "account"; 
       qe.ColumnSet = new ColumnSet("accountnumber", "new_vatno", "new_registrationnumber"); 
       qe.Criteria.AddCondition("accountnumber", ConditionOperator.In,'list of account numbers go here' 

    EntityCollection response = service.RetrieveMultiple(qe); 

       foreach (var acc in response.Entities) 
       { 
        if (crmAcc.Account_No == acc.Attributes["accountnumber"].ToString()) 
        { 
         //acc.Attributes["new_vatno"] = crmAcc.VAT_No.ToString(); 
         acc.Attributes["new_registrationnumber"] = crmAcc.Reg_No.ToString(); 

         service.Update(acc); 
        } 

       } 
      } 
Verwandte Themen