|
22.05.2012, 02:12 | #1 |
Участник
|
emeadaxsupport: Calling the Update Operation on Services in AX 2012
Источник: http://blogs.msdn.com/b/axsupport/ar...n-ax-2012.aspx
============== Calling the update operation on web services can range from simple to very complicated depending on the entities/tables you are updating. If the entity you are calling is not a date effective entity, then the service's update method is easy to call. You can tell if a table is date effective by going in the AOT to the Data Dictionary > Tables > Find the tables that comprise the service > Right-click on the table and choose Properties. In the property sheet, look for the ValidTimeStateFieldType property. If the property is set to "None" then the table is NOT date effective. You will need to look at every table in the service to see if that property is set to none. If the service is not date effective, like the sales order service, then you can call the service using the find and then the update operations. In the example below, I retrieve a sales order using the find method and then I update the SalesQty and SalesPrice fields on each sales line in the retrieved sales order. static void Main(string[] args) { //First find the order AxdSalesOrder salesOrder = Program.FindOrder(); //Now update it Program.UpdateOrder(salesOrder); } static AxdSalesOrder FindOrder() { CallContext context = new CallContext(); context.Company = "ceu"; string salesId = "SO-101244"; AxdSalesOrder foundSalesOrder = null; //Instantiate an instance of the service client class SalesOrderServiceClient proxy = new SalesOrderServiceClient(); try { foundSalesOrder = proxy.find(context, Program.createQueryCriteria(salesId)); Console.WriteLine("The sales order was found."); } catch (Exception e) { Console.WriteLine("The sales order was not found."); } return foundSalesOrder; } private static QueryCriteria createQueryCriteria(string salesIdValue) { CriteriaElement[] criteriaElements = new CriteriaElement[1]; criteriaElements[0] = new CriteriaElement(); criteriaElements[0].DataSourceName = "SalesTable"; criteriaElements[0].FieldName = "SalesId"; criteriaElements[0].Value1 = salesIdValue; QueryCriteria queryCriteria = new QueryCriteria(); queryCriteria.CriteriaElement = criteriaElements; return queryCriteria; } static void UpdateOrder(AxdSalesOrder salesOrder) { CallContext context = new CallContext(); context.Company = "ceu"; SalesOrderServiceClient proxy = new SalesOrderServiceClient(); foreach (AxdEntity_SalesTable salesTable in salesOrder.SalesTable) { foreach (AxdEntity_SalesLine salesLine in salesTable.SalesLine) { salesLine.SalesQty = salesLine.SalesQty + 1; salesLine.SalesPrice = salesLine.SalesPrice + 2; salesLine.SalesPriceSpecified = true; } } try { proxy.update(context, Program.createEntityKeyList(), salesOrder); Console.WriteLine("The sales order was successfully updated"); } catch (Exception e) { Console.WriteLine("The sales order was not updated."); } } Unlike the sales order service, the customer service is date effective because it contains the DirPersonName, DirOrganizationName, DirPartyLocation, etc. tables which have their ValidTimeStateFieldType properties set to something other than None. Date effective services have properties added at the document level (the highest level in the service) to indicate how you want to set the date effective entities. The properties are ValidTimeStateType, ValidAsOfDateTime, ValidFromDateTime and ValidToDateTime. Either you can set those at the document level or you can set the date effective fields on each entity in the service that is date effective. In the example code below, I call the read method to retrieve a customer and then I create a new instance of a customer, set the date effective properties on the document according to what they are on the retrieved customer and then update the CreditMax field on the customer. static void Main(string[] args) { string customer = "1104"; AxdCustomer foundCustomer = null; CallContext context = new CallContext(); context.Company = "ceu"; CustomerServiceClient proxy = new CustomerServiceClient(); try { foundCustomer = proxy.read(context, Program.readCritera(customer)); Console.WriteLine("Read worked"); Program.updateCustomer(foundCustomer); } catch (Exception e) { Console.WriteLine(e.Message); } } private static EntityKey[] readCritera(string customerAccount) { AxdEntity_CustTable custTable = new AxdEntity_CustTable(); EntityKey[] entityKeyList = new EntityKey[1]; EntityKey key = new EntityKey(); KeyField[] keyFields = new KeyField[1]; KeyField keyField = new KeyField(); keyField.Field = "AccountNum"; keyField.Value = customerAccount; keyFields[0] = keyField; key.KeyData = keyFields; entityKeyList[0] = key; return entityKeyList; } private static void updateCustomer(AxdCustomer customer) { CustomerServiceClient proxy = new CustomerServiceClient(); CallContext context = new CallContext(); context.Company = "ceu"; AxdEntity_CustTable custTable = customer.CustTable[0]; AxdCustomer axdCustomer2 = new AxdCustomer(); axdCustomer2.ValidTimeStateType = customer.ValidTimeStateType; axdCustomer2.ValidTimeStateTypeSpecified = true; axdCustomer2.ValidAsOfDateTime = customer.ValidAsOfDateTime; axdCustomer2.ValidFromDateTime = customer.ValidFromDateTime; axdCustomer2.ValidToDateTime = customer.ValidToDateTime; AxdEntity_CustTable custTableNew = new AxdEntity_CustTable(); custTableNew._DocumentHash = custTable._DocumentHash; custTableNew.RecId = custTable.RecId; custTableNew.RecVersion = custTable.RecVersion; custTableNew.action = AxdEnum_AxdEntityAction.update; custTableNew.actionSpecified = true; custTableNew.CreditMax = custTable.CreditMax + 10; custTableNew.CreditMaxSpecified = true; custTableNew.CustGroup = custTable.CustGroup; axdCustomer2.CustTable = new AxdEntity_CustTable[1] { custTableNew }; try { proxy.update(context, Program.readCritera("1104"), axdCustomer2); Console.Write("Worked"); Console.ReadLine(); } catch (Exception e) { Console.WriteLine("Failed"); Console.ReadLine(); } } As an alternative to setting the properties at the document level (AxdCustomer) I can set the date effective properties on each table in the service that is date effective. As you'll notice the code get clunkier and more difficult to do programmatically. The example code below accomplishes the same goal of retrieving the customer using the read method and then it updates the CreditMax for that customer. static void Main(string[] args) { string customer = "1104"; AxdCustomer foundCustomer = null; CallContext context = new CallContext(); context.Company = "ceu"; CustomerServiceClient proxy = new CustomerServiceClient(); try { foundCustomer = proxy.read(context, Program.readCritera(customer)); AxdEntity_DirParty_DirPartyTable returnedPartyTable = foundCustomer.CustTable[0].DirParty[0]; Console.WriteLine("Read worked"); Program.updateCustomer(foundCustomer); } catch (Exception e) { Console.WriteLine(e.Message); } } private static EntityKey[] readCritera(string customerAccount) { AxdEntity_CustTable custTable = new AxdEntity_CustTable(); EntityKey[] entityKeyList = new EntityKey[1]; EntityKey key = new EntityKey(); KeyField[] keyFields = new KeyField[1]; KeyField keyField = new KeyField(); keyField.Field = "AccountNum"; keyField.Value = customerAccount; keyFields[0] = keyField; key.KeyData = keyFields; entityKeyList[0] = key; return entityKeyList; } private static void updateCustomer(AxdCustomer customer) { CustomerServiceClient proxy = new CustomerServiceClient(); CallContext context = new CallContext(); context.Company = "ceu"; foreach (AxdEntity_CustTable custTable in customer.CustTable) { custTable._DocumentHash = custTable._DocumentHash; custTable.RecId = custTable.RecId; custTable.RecVersion = custTable.RecVersion; custTable.action = AxdEnum_AxdEntityAction.update; custTable.actionSpecified = true; custTable.CreditMax = custTable.CreditMax + 10; custTable.CreditMaxSpecified = true; #region Update the date effective entities AxdEntity_DirParty_DirOrganization dirPartyTable = (AxdEntity_DirParty_DirOrganization)custTable.DirParty[0]; dirPartyTable.action = AxdEnum_AxdEntityAction.update; dirPartyTable.actionSpecified = true; AxdEntity_OrganizationName orgName = dirPartyTable.OrganizationName[0]; orgName.action = AxdEnum_AxdEntityAction.update; orgName.actionSpecified = true; orgName.updateMode = AxdEnum_ValidTimeStateUpdate.Correction; orgName.updateModeSpecified = true; //Update the postal addresses AxdEntity_DirPartyPostalAddressView[] postalAddresses = dirPartyTable.DirPartyPostalAddressView; foreach (AxdEntity_DirPartyPostalAddressView postalAddress in postalAddresses) { postalAddress.action = AxdEnum_AxdEntityAction.update; postalAddress.actionSpecified = true; postalAddress.updateMode = AxdEnum_ValidTimeStateUpdate.Correction; postalAddress.updateModeSpecified = true; postalAddress.RecId = postalAddress.RecId; postalAddress.RecVersion = postalAddress.RecVersion; postalAddress.Roles = "Home"; } //Update the electronic addresses AxdEntity_DirPartyContactInfoView[] electronicAddresses = dirPartyTable.DirPartyContactInfoView; foreach (AxdEntity_DirPartyContactInfoView electronicAddress in electronicAddresses) { electronicAddress.action = AxdEnum_AxdEntityAction.update; electronicAddress.actionSpecified = true; electronicAddress.updateMode = AxdEnum_ValidTimeStateUpdate.Correction; electronicAddress.updateModeSpecified = true; electronicAddress.RecId = electronicAddress.RecId; electronicAddress.RecVersion = electronicAddress.RecVersion; } } #endregion try { proxy.update(context, Program.readCritera("1104"), customer); Console.Write("Worked"); Console.ReadLine(); } catch (Exception e) { Console.WriteLine("Failed"); Console.ReadLine(); } } } Источник: http://blogs.msdn.com/b/axsupport/ar...n-ax-2012.aspx
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
|
|