Managed DataSet – Part 2. Enumerating Rows.
As promised in part 1 I will continue with discussing the new Managed DataSet and in particular focus on how to write code that uses the DataSet. As I am writing this I realize that there will be many parts to this saga which will gradually uncover more and more parts of the DataSet and its related classes. As is customary I will start with discussing the basics and then move forward from there.
So in this post I will show how to create and run a DataSet and how to enumerate the rows in a DataSetView in order to print some of the field values. The code for this post is located here.
The first step is to create the DataSet and in order to that I need an AX session – the following code which is part of a simple class does exactly that.
The static ISession object is instantiated via the SessionCache object which in this case will return a non-cached standard AX session i.e. it logs on to AX via BC.NET. The CreateAndRun function will create a DataSet by calling the DataSet constructor which takes the AOT node of a DataSet. It will then also “run” the dataset by calling Run which effectively calls ExecuteQuery on all the form datasources in the dataset. In other words run will fill the dataset with data.
For this example I will use the tutorial DataSet that is shipped with AX 2009 called tutorial_CustomerDetail. The dataset consists of one dataset view constructed by the inner join of the ContactPerson table to the CustTable. The CreateAndRun method above is this used as follows to create the dataset.
The code then continues to print the values of the AccountNum and ContactPerson!Name fields for all the rows in the CustTable dataset view. A couple of things are worht noticing here. First is how the dataset view is accessed. The DataSet contains a collection that is keyed by index and by dataset view name of all the views in the dataset (for further discussion of views go here). The name of a view is the name of master form datasource in the view which in this case is CustTable since the ContactPerson form datasource is inner joined to the CustTable form datasource. Secondly notice the name of the second field in the field list that I want to print the values of. Because the view consists of all the fields from two tables the fields of the child tables are prefixed with their name to avoind conflicts e.g. all tables in AX have RecId so in order to distinguish between CustTable.RecId and ContactPerson.RecId in the above exmaple the fields from ContactPerson are prefixed with ContactPerson! e.g. ContactPerson!Name.
The PrintDataSetViewRows function will enumerate all the rows in the dataset view which is possible because the DataSetView class implements IList and this IEnumerable.
And finally I call PrintRowValues for each DataSetViewRow in the dataset view in order to print the actual values of the fields in the row.
The code uses the managed metadata object model defined in the Microsoft.Dynamics.Framework.Metadata.Ax namespace to lookup the label of the field. The metadata object model contains a set of classes that describes the metadata for many of the objects in the AOT making it easy to access the metadata from managed code. In this case here I grab the label so I can print it together with the actual field value. To get the field value I call the GetFieldValue function the DataSetViewRow.
The output when calling the above ReadFieldValues from a console app is shown below. You might be suprised that you only see 10 records but that is because the dataset by default has paging enabled with the page size set to 10. To disable or change the paging parameters you call the SetPagingParameters function on the DataSetView class which takes the PagingParameters struct as a parameter.
Furthermore notice the effect of the inner join between the CustTable and the ContactPerson table i.e. some rows from CustTable are repeated in order to produce the join.
Comments
Anonymous
September 22, 2008
Not totally related to this topic, but i have one question. Is it possible to persist the filter that is applied when an AxGridView is used? The filter is always reset when the user opens the web pageAnonymous
October 27, 2008
As promised in part 1 I will continue with discussing the new Managed DataSet and in particular focusAnonymous
November 26, 2008
I have tried the following from a standard winform. ISession session = SessionCache.GetSession(NoCacheContext.Instance, DynamicsSession.Factory.Instance); Microsoft.Dynamics.Framework.Data.Ax.DataSet dataset = new Microsoft.Dynamics.Framework.Data.Ax.DataSet(session, "tutorial_CustomerDetail"); dataset.Run(); The session is created and the dataset are instantiated all right, but the run method causes an infinite loop and the program uses 100% cpu. Isn't is possible to do this from the environment of a winform??Anonymous
February 02, 2009
I have tried this from Asp.Net website. I got all the dataset information: metadata, rowcount,... But the run did the same as Lars said. The problem is maybe in the ?FormDataSourceRun? ax class run method, but that's a kernel class, so i couldn't debug it. If u know a solution please mail me to hepeter@xapt.hu ThanksAnonymous
July 24, 2009
Hi, I Am using similar code ina scenario where a page has got multiple webparts.I am trying to get the current record selected in the related webpart based upon the parent webpart.eg selected contactperson based on customer and move to some related page. But this code is not working.It is throwing the following error -- Session Release for Microsoft Dynamics failed. No .NET Business Connector session could be found. Microsoft.Dynamics.Framework.BusinessConnector.Session.Exceptions.NoKernelSessionException at Microsoft.Dynamics.Framework.BusinessConnector.Session.DynamicsSession.get_AxaptaAdapter() at Microsoft.Dynamics.Framework.Portal.AxWebSession.WebSessionClientRemove() at Microsoft.Dynamics.Framework.Portal.AxWebSession.OnRelease(IAxaptaAdapter axaptaAdapter) at Microsoft.Dynamics.Framework.BusinessConnector.Session.DynamicsSession.Release(ICacheContext context) This is the most common error which comes in any scenario. Is there any solution/workaround for it. Appreciate any help.