Quantcast
Channel: Microsoft Dynamics 365 Community
Viewing all articles
Browse latest Browse all 53708

C# - AX AIF webservice apply company filer/field filter to existing AOT query or create query on the fly within c#

$
0
0
Per the past previous posts of showing how to create a query within AX and calling it via the AIF in C# I ran into the dilemma of needing to add a company filter to said defined query on the fly within the C# application.
You can do this multiple ways. You can also use the examples on how to apply any filter to a query on the fly. If you are not applying filters than the static query example(s) shown in the previous post would be the way to go.

1. Create the query on the fly via code. Apply filter via code.
Pros: complete control over the structure of the query, no need for AOT object, good for small querys with only a couple tables/fields, only 1 webservice connection is needed
Cons: lots and lots of code in order to do this. The more complex the query the more code that is needed to do this, have to define every field you want to add unless you want all fields
Services needed: QueryService: http://<AOSServer>:8101/DynamicsAx/Services/QueryService
Code Example:
  string axCompanyName = "<company name within AX/dataAreaId>";
  DataSet dataSet;
  AXQueryService.QueryMetadata query = new AXQueryService.QueryMetadata();
                AXQueryService.QueryServiceClient client = new AXQueryService.QueryServiceClient();
                AXQueryService.Paging paging = null;
                query.DataSources = new AXQueryService.QueryDataSourceMetadata[2];
                query.Name = "AXCustomerInfo";
                //set up the main customer table to pull the id from
                AXQueryService.QueryDataSourceMetadata custTableDS = new AXQueryService.QueryDataSourceMetadata();
                custTableDS.Name = "CustTable";
                custTableDS.Table = "CustTable";
                custTableDS.Enabled = true;
                //define the current company to search by within AX
                custTableDS.Company = axCompanyName;
                //define the main datasource
                query.DataSources[0] = custTableDS;
                //define the field listing so we dont pull in all fields
                custTableDS.DynamicFieldList = false;
                custTableDS.Fields = new AXQueryService.QueryDataFieldMetadata[1];
               
                AXQueryService.QueryDataFieldMetadata accountNum;
                accountNum = new AXQueryService.QueryDataFieldMetadata();
                accountNum.FieldName = "AccountNum";
                accountNum.SelectionField = AXQueryService.SelectionField.Database;
                custTableDS.Fields[0] = accountNum;
      
                //let the query know we need to join the table
                custTableDS.HasRelations = true;
                custTableDS.JoinMode = AXQueryService.JoinMode.InnerJoin;
                //add the dirtparty table to the query so we can pull in the name
                AXQueryService.QueryDataSourceMetadata dirPartyTableDS = new AXQueryService.QueryDataSourceMetadata();
                dirPartyTableDS.Name = "DirPartyTable";
                dirPartyTableDS.Table = "DirPartyTable";
                dirPartyTableDS.Enabled = true;
                //define the current company to search by within AX
                dirPartyTableDS.Company = axCompanyName;
               
                //define the sub datasource
                query.DataSources[1] = dirPartyTableDS;
               
                //define the field listing so we dont pull in all the fields
                dirPartyTableDS.DynamicFieldList = false;
                dirPartyTableDS.Fields = new AXQueryService.QueryDataFieldMetadata[1];
               
                AXQueryService.QueryDataFieldMetadata name;
                name = new AXQueryService.QueryDataFieldMetadata();
                name.FieldName = "Name";
                name.SelectionField = AXQueryService.SelectionField.Database;
                dirPartyTableDS.Fields[0] = name;
                dirPartyTableDS.HasRelations = false;
           
                //execute the new dynamic query
                dataSet = client.ExecuteQuery(query, ref paging);



2. Create AOT query object. Read in properties(meta data) from the AOT object, apply filter and run query.
Pros: complex queries can be defined and managed within the AOT, less code is needed
Cons: You need to use 2 services instead of 1 (Query & MetaData Services, both are built into default AX)
Services needed: QueryService: http://<AOSServer>:8101/DynamicsAx/Services/QueryService / Metadata Service: http://<AOSServer>:8101/DynamicsAx/Services/MetadataService
Code Example:
 
  string axCompanyName = "<company name within AX/dataAreaId>";
  DataSet dataSet;
  AXMetadataService.AxMetadataServiceClient metaClient = new AXMetadataService.AxMetadataServiceClient();
                AXQueryService.QueryServiceClient client = new AXQueryService.QueryServiceClient();
               
                AXMetadataService.QueryMetadata metaQuery = metaClient.GetQueryMetadataByName(new string[] { "<aot query object name>" })[0];
                AXQueryService.QueryMetadata query = new AXQueryService.QueryMetadata();
               
                AXQueryService.Paging paging = null;
             
                //convert the metadataservice metadata to the queryservice metadata so we can execute the query with the properties/metadata found on the aot query object
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    DataContractSerializer metaSerializer = new DataContractSerializer(typeof(AXMetadataService.QueryMetadata));
                    DataContractSerializer querySerializer = new DataContractSerializer(typeof(AXQueryService.QueryMetadata));
                   
                    metaSerializer.WriteObject(memoryStream, metaQuery);
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    query = (AXQueryService.QueryMetadata)querySerializer.ReadObject(memoryStream);
                }

                //define the company filter based on what the user has selected
                query.DataSources[0].Company = axCompanyName;
                query.DataSources[0].DataSources[0].Company = axCompanyName;
             
                //execute the query and get the results
                dataSet = client.ExecuteQuery(query, ref paging);

As you can see both examples return the same results however the 2nd example is far less code. The example were using only has 2 fields that are being returned but on a more complex query that may contain 5-10 tables and more fields its pretty easy to tell that the easy way to go is to define the query within the AOT and get the properties , apply filter, execute query (2nd example)


You can also apply a filter to any range/field via the following method (this would work on both examples)
  AXQueryService.QueryDataRangeMetadata range = new AXQueryService.QueryDataRangeMetadata()
  {
    Enabled = true,
    FieldName = "dataAreaId",
    Value = axCompanyName
  };
   query.DataSources[0].Ranges = new AXQueryService.QueryRangeMetadata[] { range };

Viewing all articles
Browse latest Browse all 53708

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>