I strongly believe that the blog content consists of two equally important parts – author's input (through the posts) and readers' input (through the comments).
And so I decided to try to boost the second part a little bit and I need your help here.
This post will stay on top since now and I am asking you to write in comments to this post anything you will be interested to read about in this blog.
It can be a request to explain some AX 2012 feature, suggestion of the topic\tip\trick that might be interesting to others, bug report, … basically anything. And I will be replying to that with posts.
And I would also like to welcome you to comment\ask questions\start discussions in all other posts as well.
Thanks!
Dynamics AX Daily
Tuesday, May 5, 2020
Friday, February 17, 2012
New AX 2012 intrinsic functions
Two new intrinsic functions were added in AX 2012. One to reference datasources of queries and another one to reference form controls:
Just want to remind the benefits of using intrinsic functions comparing to plain strings:
Just want to remind the benefits of using intrinsic functions comparing to plain strings:
- If the referenced object changes name the problem will be detected in compile time
- The reference will be reflected as a cross-reference, making the dependencies more transparent
Wednesday, February 8, 2012
More on CIL debugging
In the case you don't like debugging X++ code in Visual Studio there is a way to prevent code execution in CIL and to use the standard AX debugger instead.
This can be done in the Tools->Options form.
Friday, May 13, 2011
Debugging managed code in AX 2012
Since a lot of X++ code is now executed in CLR there should be a possibility to debug it. The standard AX debugger cannot help here since it is capable of debugging interpreted code only. However, Visual Studio 2010 can do the job.
There are few steps needed to be able to debug managed X++ execution using VS:
After that you can locate the source code and place the breakpoint. This can be done either using Application Explorer, or by opening .xpp source file directly from the [AX server path]\bin\XppIL\Source folder. Each method of each class or table has a separate .xpp file that is named [ClassName].[MethodName].xpp.
And that’s it. Now the debugging will happen is visual studio. Call stack, watches, etc. are also available.
There are few steps needed to be able to debug managed X++ execution using VS:
- Breakpoints should be enabled on server (in AOS configuration).
- Visual Studio should be started with elevated permissions (run as administrator).
- Visual Studio should be attached to Ax32Serv.exe process (AOS process).
After that you can locate the source code and place the breakpoint. This can be done either using Application Explorer, or by opening .xpp source file directly from the [AX server path]\bin\XppIL\Source folder. Each method of each class or table has a separate .xpp file that is named [ClassName].[MethodName].xpp.
And that’s it. Now the debugging will happen is visual studio. Call stack, watches, etc. are also available.
Tuesday, May 10, 2011
Visual studio tools for AX 2012
Now it became really easy to develop managed components for AX.
In order to do that you’ll need Visual Studio 2010 and Visual Studio Tools for AX 2012.
The first tool to mention is, of course, Application Explorer. It contains elements from AOT (and it actually looks pretty much like AOT) and allows to perform some operations with them. For example, it is possible to open projects or SSRS reports stored in AOT in the same visual studio instance just by clicking edit on project node in application explorer.
Application Explorer also allows to generate proxies for AX tables, classes, enums and add them to the project. Just by dragging them from application explorer to solution explorer.
It is also very important to mention that VS projects can now be stored in the AOT. That is convenient since they can be included into models, as well as all other AOT objects and thus packaged\deployed easily.
Project can be added to the AOT from the Visual Studio directly.
In order to do that you’ll need Visual Studio 2010 and Visual Studio Tools for AX 2012.
The first tool to mention is, of course, Application Explorer. It contains elements from AOT (and it actually looks pretty much like AOT) and allows to perform some operations with them. For example, it is possible to open projects or SSRS reports stored in AOT in the same visual studio instance just by clicking edit on project node in application explorer.
Application Explorer also allows to generate proxies for AX tables, classes, enums and add them to the project. Just by dragging them from application explorer to solution explorer.
It is also very important to mention that VS projects can now be stored in the AOT. That is convenient since they can be included into models, as well as all other AOT objects and thus packaged\deployed easily.
Project can be added to the AOT from the Visual Studio directly.
Wednesday, May 4, 2011
Unit of Work
After the post about surrogate keys I was asked the following question:
There is the following problem with using surrogate keys.
A record gets RecId value at the moment it is inserted into the database. What if we are doing bulk insert of a journal with many lines and the journal header contains some totals calculated based on its lines. It is impossible to insert lines before header since the value of the journal's surrogate key is unknown. But that would be so convenient because otherwise the header should be inserted first, then the lines and then the header should be updated with the calculated totals.
The answer is – use Unit of Work. It allows to perform create, update and delete operations without worrying about the order of those and without a need to specify surrogate key values. It will all be done automatically in the kernel!
Example:
Let we have the following tables:
The following job will insert the journal header with calculated totals and 10 lines. Note, that there is no place where surrogate keys are mentioned in the code. Business data only.
And here is the result.
Some more details about the unit of work feature:
And the last but not least. AX client has the great support of the unit of work as well. This means that form datasources can be grouped into a unit of work, so all the benefits of simultaneous commit and surrogate key propagation will be available on forms. There are a lot of possibilities and tricks there, so this topic worth one or more dedicated posts as well.
There is the following problem with using surrogate keys.
A record gets RecId value at the moment it is inserted into the database. What if we are doing bulk insert of a journal with many lines and the journal header contains some totals calculated based on its lines. It is impossible to insert lines before header since the value of the journal's surrogate key is unknown. But that would be so convenient because otherwise the header should be inserted first, then the lines and then the header should be updated with the calculated totals.
The answer is – use Unit of Work. It allows to perform create, update and delete operations without worrying about the order of those and without a need to specify surrogate key values. It will all be done automatically in the kernel!
Example:
Let we have the following tables:
The following job will insert the journal header with calculated totals and 10 lines. Note, that there is no place where surrogate keys are mentioned in the code. Business data only.
And here is the result.
Some more details about the unit of work feature:
- All database operations happen only when saveChanges() method is invoked.
- UnitOfWork class has insertOnSaveChanges(), updateOnSaveChanges() and deleteOnSaveChanges() methods for CUD operations.
- Surrogate keys can be propagated automatically to related records if buffers are linked via navigation methods (AJournalLine.header() method in the example). Navigation methods can be created automatically from relations. I’ll write a separate post about them.
And the last but not least. AX client has the great support of the unit of work as well. This means that form datasources can be grouped into a unit of work, so all the benefits of simultaneous commit and surrogate key propagation will be available on forms. There are a lot of possibilities and tricks there, so this topic worth one or more dedicated posts as well.
Tuesday, May 3, 2011
Surrogate keys in AX 2012
Data modeling enhancements were prioritized really high in AX 2012. I already mentioned one earlier – table inheritance, but there are a lot of other important features about data modeling.
One such feature is the support of surrogate keys. Surrogate keys recommended themselves as a very good solution for complex databases because of their beneficial properties, like immutability, robustness to redesign and performance. And now this best practice is coming to AX. It is the recommendation for AX 2012 to use surrogate keys for all new tables, unless there is a good reason not to do so.
Actually, previous versions of AX already have surrogates – RecIds. And it was possible to introduce surrogate key just by setting CreateRecIdIndex table property to Yes. But there is a problem with the inconvenience of working with surrogates in the UI. Imagine InventTable using surrogate key and all other tables that have relations to InventTable using its surrogate key as a foreign key. Then on any form where ItemId should be displayed (let’s say on the SalesTable) an extra join to InventTable will be needed to fetch the ItemId. And what if user can change the item? Then even more custom logic is needed to resolve the entered ItemId to the corresponding surrogate key value and write it to the SalesLine.
This inconvenience actually was a showstopper. But not anymore. AX 2012 got kernel support for surrogate key substitution. And not only in forms, but in Axd document services and even in the debugger.
Let me show an example of how it works:
UnitOfMeasure table uses surrogate key as a primary key. However, the user-friendly identifier of the UnitOfMeasure table records is the UnitOfMeasureSymbol field. This field is a part of the SymbolIdx index, which is specified as a replacement key on the UnitOfMeasure table.
This setup basically means that surrogate key values (RecIds) of the UnitOfMeasure table records will be automatically substituted in the UI with the replacement key values (UnitOfMeasureSymbols).
UnitOfMeasureConversion table has a relation to the UnitOfMeasue table through the surrogate key.
As you can see, on the UnitOfMeasureConversion form there are only UnitOfMeasureConversion datasources. And you can notice new ReferenceGroup control which is bound to the FromUnitOfMeasure field (which contains surrogate values).
And in the UI it will look just like UnitOfMeasureSymbol field is shown instead. And it can also be modified and that will be handled automatically, without a single line of code.
Actually ReferenceGroup control has much more interesting capabilities and thus deserves a separate post.
One such feature is the support of surrogate keys. Surrogate keys recommended themselves as a very good solution for complex databases because of their beneficial properties, like immutability, robustness to redesign and performance. And now this best practice is coming to AX. It is the recommendation for AX 2012 to use surrogate keys for all new tables, unless there is a good reason not to do so.
Actually, previous versions of AX already have surrogates – RecIds. And it was possible to introduce surrogate key just by setting CreateRecIdIndex table property to Yes. But there is a problem with the inconvenience of working with surrogates in the UI. Imagine InventTable using surrogate key and all other tables that have relations to InventTable using its surrogate key as a foreign key. Then on any form where ItemId should be displayed (let’s say on the SalesTable) an extra join to InventTable will be needed to fetch the ItemId. And what if user can change the item? Then even more custom logic is needed to resolve the entered ItemId to the corresponding surrogate key value and write it to the SalesLine.
This inconvenience actually was a showstopper. But not anymore. AX 2012 got kernel support for surrogate key substitution. And not only in forms, but in Axd document services and even in the debugger.
Let me show an example of how it works:
UnitOfMeasure table uses surrogate key as a primary key. However, the user-friendly identifier of the UnitOfMeasure table records is the UnitOfMeasureSymbol field. This field is a part of the SymbolIdx index, which is specified as a replacement key on the UnitOfMeasure table.
This setup basically means that surrogate key values (RecIds) of the UnitOfMeasure table records will be automatically substituted in the UI with the replacement key values (UnitOfMeasureSymbols).
UnitOfMeasureConversion table has a relation to the UnitOfMeasue table through the surrogate key.
As you can see, on the UnitOfMeasureConversion form there are only UnitOfMeasureConversion datasources. And you can notice new ReferenceGroup control which is bound to the FromUnitOfMeasure field (which contains surrogate values).
And in the UI it will look just like UnitOfMeasureSymbol field is shown instead. And it can also be modified and that will be handled automatically, without a single line of code.
Actually ReferenceGroup control has much more interesting capabilities and thus deserves a separate post.
Monday, May 2, 2011
SQL temporary tables in AX 2012
In AX 2012 a new type of tables was introduced.
In addition to Regular (permanent) tables and InMemory tables (known as temporary tables in previous versions of AX) we have got TempDB tables - SQL server temporary tables.
I believe thit is the feature that many people expected for a long time. TempDB tables utilize the power of SQL tables - full support of joins, aggregation, indexes, all with great performance, but in the same time they have almost the same scoping mechanism as InMemory temporary tables have.
That simplifies developer's life significantly. There is no more need to be aware of tricks like this or like this.
In addition to Regular (permanent) tables and InMemory tables (known as temporary tables in previous versions of AX) we have got TempDB tables - SQL server temporary tables.
I believe thit is the feature that many people expected for a long time. TempDB tables utilize the power of SQL tables - full support of joins, aggregation, indexes, all with great performance, but in the same time they have almost the same scoping mechanism as InMemory temporary tables have.
That simplifies developer's life significantly. There is no more need to be aware of tricks like this or like this.
Friday, April 29, 2011
WCF services in AX 2012
Since X++ can be compiled to CIL in AX 2012 it became possible to change the way how X++ services are implemented.
Now all X++ services are WCF services and they are executed in the WCF runtime hosted on the AOS.
It is really hard to overestimate the benefits of this feature. Let me mention here just a few of those:
It is really nice to see that powerful and standardized technologies are coming to AX.
And one more thing to mention. In AX 2012 all AIF and services concepts were simplified significantly. Just look how AIF menu section was changed:
And most of the setup can be done now just from this very nice form:
Now all X++ services are WCF services and they are executed in the WCF runtime hosted on the AOS.
It is really hard to overestimate the benefits of this feature. Let me mention here just a few of those:
- Every service has now WSDL definition. This means that it is extremely easy to generate proxy classes for those services for external clients using standard tools like svcutil.exe (add service reference in VS) or WSDL2java.
- There is a new protocol to communicate with AOS now – WCF, in addition to the regular RPC.
- Seamless integration with many applications\technologies, like MSMQ or BizTalk.
- Simple and standard security model.
It is really nice to see that powerful and standardized technologies are coming to AX.
And one more thing to mention. In AX 2012 all AIF and services concepts were simplified significantly. Just look how AIF menu section was changed:
And most of the setup can be done now just from this very nice form:
AX 2012 user interface and style property
In AX 2012 user interface has been changed significantly. AX looks now much more modern and I would say, Office 2010-like.
However there were not so many new controls added (I will write about each of them separately). The variety of different visual experiences can be achieved now with the new extremely cool property of form controls – Style.
This property defines general look & feel of the control, which can be then customized with other properties.
For example, Tab control has the following styles:
FastTabs
VerticalTabs
IndexTabs
And regular AX 2009-like tabs, by the way, – Tabs.
Action pane can be with Standard or Strip style.
Standard
Strip
Form design has a lot of styles, like ListPage, DetailsFormMaster, Dialog, SimpleList, Lookup and others.
DropDialog
Many other controls have style property as well. This property really helps to change the visual appearance of control in the very easy way.
However there were not so many new controls added (I will write about each of them separately). The variety of different visual experiences can be achieved now with the new extremely cool property of form controls – Style.
This property defines general look & feel of the control, which can be then customized with other properties.
For example, Tab control has the following styles:
FastTabs
VerticalTabs
IndexTabs
And regular AX 2009-like tabs, by the way, – Tabs.
Action pane can be with Standard or Strip style.
Standard
Strip
Form design has a lot of styles, like ListPage, DetailsFormMaster, Dialog, SimpleList, Lookup and others.
DropDialog
Many other controls have style property as well. This property really helps to change the visual appearance of control in the very easy way.
Wednesday, April 27, 2011
Models in AX 2012
There is a new concept in AX 2012 called model. Model is a container of metadata elements, like AOT objects, sources, label files, etc. The main benefit of models is the possibility to easily export and import them from\to AX. This means that model is a very convenient deployment mechanism – you can develop your feature in a separate model, export it and then deploy to production environment or distribute it to your customers.
New command line tool AxUtil.exe is shipped together with AX 2012 and allows to perform operations with models in a very easy way.
AX development workspace supports models very well. It is possible to see to which model any AOT element belongs to, move AOT elements between models, create project from model, etc. AX version control system integration has model support as well. For example, it is possible to store xpos for different models in different folders in the file system.
You can read more about models in the great series of posts by mfp:
AX models – Part 1 – Deploying models
AX models – Part 2 – Manifest and signing
AX models – Part 3 – Multiple models per layer
AX models – Part 4 – Working with models inside MorphX
New command line tool AxUtil.exe is shipped together with AX 2012 and allows to perform operations with models in a very easy way.
AX development workspace supports models very well. It is possible to see to which model any AOT element belongs to, move AOT elements between models, create project from model, etc. AX version control system integration has model support as well. For example, it is possible to store xpos for different models in different folders in the file system.
You can read more about models in the great series of posts by mfp:
AX models – Part 1 – Deploying models
AX models – Part 2 – Manifest and signing
AX models – Part 3 – Multiple models per layer
AX models – Part 4 – Working with models inside MorphX
Tuesday, April 26, 2011
Table inheritance
AX 2012 supports table inheritance.
Table inheritance is controlled by the following properties:
Polymorphism is supported for table methods. All tables instance methods are virtual.
There is also client support for table hierarchies. Whenever a table that has derived tables is added on a form as a datasource, all its children are added under the derived datasources node. Fields from derived datasources can be bound to form controls and derived datasources can be used in form query construction, e.g. other datasources can be joined to derived ones.
Whenever a “New record” action is invoked on a form control that is bound to an abstract table, the following dialog will be presented to user where it is possible to select the concrete type of the record being created.
Table inheritance is controlled by the following properties:
- SupportInheritance – specifies if a table is a part of a hierarchy.
- InstanceRelationType – specifies the field that is used as a type discriminator. TableIds of concrete types are used as values of the InstanceRelationType field.
- Abstact – specifies if a table is abstract. Tables without derived tables cannot be abstract.
- Extends – specifies table’s parent.
Polymorphism is supported for table methods. All tables instance methods are virtual.
There is also client support for table hierarchies. Whenever a table that has derived tables is added on a form as a datasource, all its children are added under the derived datasources node. Fields from derived datasources can be bound to form controls and derived datasources can be used in form query construction, e.g. other datasources can be joined to derived ones.
Whenever a “New record” action is invoked on a form control that is bound to an abstract table, the following dialog will be presented to user where it is possible to select the concrete type of the record being created.
Friday, April 22, 2011
X++ attributes
AX 2012 supports attributes for classes and methods. There are quite a lot of attributes provided out of the box, mostly in AIF, Services, Upgrade, SysTest areas and it is also possible to create new attributes by inheriting from the SysAttribute class.
Attributes can really simplify many frameworks. For example, in the upgrade framework initPreSyncJobs() and initPostSyncJobs() methods, that contained usually quite a large amount of upgrade jobs and dependencies registration code, were effectively deprecated. All the registration is performed now via attributes that are attached to upgrade methods.
Attributes can really simplify many frameworks. For example, in the upgrade framework initPreSyncJobs() and initPostSyncJobs() methods, that contained usually quite a large amount of upgrade jobs and dependencies registration code, were effectively deprecated. All the registration is performed now via attributes that are attached to upgrade methods.
Thursday, April 21, 2011
X++ can be compiled to CIL in AX 2012
In AX 2012 X++ code can be compiled into CIL and executed in CLR environment hosted on the application object server. This means X++ became almost a .NET language. Almost, because there are still some X++ artifacts that can only be interpreted, for example forms. However the vast majority of server-side code can be compiled into CIL.
Because of that it is important to remember to regenerate CIL after changes have been done to the code. Since CIL compilation takes quite some time, it is not done automatically during regular X++ compilation. There are new compilation commands – Generate Incremental CIL (rebuilds assemblies that are affected by the change) and Generate Full CIL (rebuilds all assemblies). Those commands are applicable to the whole application and not to a specific X++ object (class, table, etc.). AX automatically determines what X++ objects should be compiled into CIL based on the registered entry points, e.g. if it is specified that some method should be executed in CLR, then the whole “using” reference tree of this method will be compiled into CIL.
There are several ways to specify that some code should be executed in CLR instead of X++ interpreter. Right now I want to show only one of them just to illustrate how easy it can be.
TestILExecution job will be executed using X++ interpreter (just in the same way as in previous AX versions), but postSalesOrderPackingSlip() method will be executed in CLR. As you can see, postSalesOrderPackingSlip() method is a standard method of a standard X++ class. Switching will happen because this method is registered as a service operation of FormLetterService service, and the service itself is a member of the AxClient service group which is deployed on the AOS.
Because of that it is important to remember to regenerate CIL after changes have been done to the code. Since CIL compilation takes quite some time, it is not done automatically during regular X++ compilation. There are new compilation commands – Generate Incremental CIL (rebuilds assemblies that are affected by the change) and Generate Full CIL (rebuilds all assemblies). Those commands are applicable to the whole application and not to a specific X++ object (class, table, etc.). AX automatically determines what X++ objects should be compiled into CIL based on the registered entry points, e.g. if it is specified that some method should be executed in CLR, then the whole “using” reference tree of this method will be compiled into CIL.
There are several ways to specify that some code should be executed in CLR instead of X++ interpreter. Right now I want to show only one of them just to illustrate how easy it can be.
TestILExecution job will be executed using X++ interpreter (just in the same way as in previous AX versions), but postSalesOrderPackingSlip() method will be executed in CLR. As you can see, postSalesOrderPackingSlip() method is a standard method of a standard X++ class. Switching will happen because this method is registered as a service operation of FormLetterService service, and the service itself is a member of the AxClient service group which is deployed on the AOS.
Wednesday, April 20, 2011
Intellisense in AX 2012
Intellisense in AX 2012 was significantly improved (or actually, redesigned). Now it is much closer to the visual studio intellisense.
Suggestions are presented to the user while typing for types (tables, classes, extended data types, etc.), class members and methods, local variables, intrinsic and global functions, keywords. Namespaces and types from the referenced .NET assemblies are also suggested.
Descriptions for methods were also improved. Now they include XML documentation for the methods. That is really helpful.
Suggestions are presented to the user while typing for types (tables, classes, extended data types, etc.), class members and methods, local variables, intrinsic and global functions, keywords. Namespaces and types from the referenced .NET assemblies are also suggested.
Descriptions for methods were also improved. Now they include XML documentation for the methods. That is really helpful.
Tuesday, April 19, 2011
Development environment in AX 2012
It wasn't easy to decide from what to start. There are so many new features and they are so important and interesting! However, there is one feature that every AX 2012 developer will use for sure.
In AX 2012 the new development environment was introduced (click on the picture to enlarge).
Now IDE is separated from the application. That means more space because of missing navigation pane, no interfering content pane that can be removed only using some tricks and the development-specific main menu.
You can also notice the beautiful visual studio-like code editor and compiler output window.
Development tools are now much more accessible. Version control parameters, for example, do not require navigating 3-levels deep menu.
Development workspace can be started by typing
ax32 - development
from command line, or by
Ctrl+Shift+W
combination from the application or another development workspace.
In AX 2012 the new development environment was introduced (click on the picture to enlarge).
Now IDE is separated from the application. That means more space because of missing navigation pane, no interfering content pane that can be removed only using some tricks and the development-specific main menu.
You can also notice the beautiful visual studio-like code editor and compiler output window.
Development tools are now much more accessible. Version control parameters, for example, do not require navigating 3-levels deep menu.
Development workspace can be started by typing
ax32 - development
from command line, or by
Ctrl+Shift+W
combination from the application or another development workspace.
Monday, April 18, 2011
AX 2012 is on the way!
So, AX 2012 will be released very soon and it means that it is the time to share some more details about it. And it also means that it is the time to revive this blog!
The amount of changes that were done in AX 2012 is just tremendous. A lot of new concepts, features, improvements and of course, small specialties and tricks! Describing all that should keep me busy for a while.
The plan for now is to make an overview of the new technological features and then look into them in much more details. However, if you are interested in details for some particular feature, let me know by leaving a comment to this post.
Ok, let’s get started! Just one very important thing prior to that:
This disclaimer is applicable to all posts about AX 2012 in this blog.
And here is the link to get the first impression of what has been done:
New, Changed, and Deprecated Features for Microsoft Dynamics AX 2012
The amount of changes that were done in AX 2012 is just tremendous. A lot of new concepts, features, improvements and of course, small specialties and tricks! Describing all that should keep me busy for a while.
The plan for now is to make an overview of the new technological features and then look into them in much more details. However, if you are interested in details for some particular feature, let me know by leaving a comment to this post.
Ok, let’s get started! Just one very important thing prior to that:
Disclaimer
All the information about AX 2012 posted here is a pre-release. Any feature is a subject to be changed before the release without notice.This disclaimer is applicable to all posts about AX 2012 in this blog.
And here is the link to get the first impression of what has been done:
New, Changed, and Deprecated Features for Microsoft Dynamics AX 2012
Monday, May 3, 2010
Overlay vs override
Microsoft is trying to achieve consistency among all the classes in AX to have the following condition met:
Each class has construct method which takes no parameters. This constructor should be the primary entry point for class construction, e.g. any other constructor should use construct() inside.
For the same reason, to avoid direct instantiation of the objects via new() method they are marked as protected. It is done in such way because it looks like overriding is much more maintainable than overlaying. It is better to create a sub-class in the outer layer that extends super-class in inner layer and overrides the required method + have construct() method overlaid to instantiate sub-class instead. Code upgrade in this case seems to be much cheaper comparing to the case when methods are overlaid directly on the super-class.
So my question basically is, if this statement is correct or not? Are you writing code in the described way? If no, why? What are the cases when overlaying is better that overriding?
Each class has construct method which takes no parameters. This constructor should be the primary entry point for class construction, e.g. any other constructor should use construct() inside.
For the same reason, to avoid direct instantiation of the objects via new() method they are marked as protected. It is done in such way because it looks like overriding is much more maintainable than overlaying. It is better to create a sub-class in the outer layer that extends super-class in inner layer and overrides the required method + have construct() method overlaid to instantiate sub-class instead. Code upgrade in this case seems to be much cheaper comparing to the case when methods are overlaid directly on the super-class.
So my question basically is, if this statement is correct or not? Are you writing code in the described way? If no, why? What are the cases when overlaying is better that overriding?
Friday, April 30, 2010
Unit tests data setup and tear down
There are methods in AX to setup data before test execution and tear it down afterwards - SysTestCase.setup() and SysTestCase.tearDown(). Those methods will be executed before and after each test method in a unit test class.
In AX 2009 two new methods were added - setupTestCase() and tearDownTestCase() which are executed only once per unit test class execution - before first test method and after last test method. But there is a problem with using them - by default each unit test method runs in a separate instance of the unit test class, so if you are setting up some data in the setupTestCase() method there will be no possibility to store a reference to it in the instance variable.
To change this behavior useSingleInstance() method can be overridden to return true. In this case all test method as well as setupTestCase() and tearDownTestCase() method will be execute in one instance of the unit test class.
In AX 2009 two new methods were added - setupTestCase() and tearDownTestCase() which are executed only once per unit test class execution - before first test method and after last test method. But there is a problem with using them - by default each unit test method runs in a separate instance of the unit test class, so if you are setting up some data in the setupTestCase() method there will be no possibility to store a reference to it in the instance variable.
To change this behavior useSingleInstance() method can be overridden to return true. In this case all test method as well as setupTestCase() and tearDownTestCase() method will be execute in one instance of the unit test class.
Wednesday, April 28, 2010
Record caching principle
Which statement will perform faster?
select inventTable
join inventItemGroup
where inventItemGroup.ItemGroupId == inventTable.ItemGroupId
&& inventTable.ItemId == 'A';
or
select inventTable
where inventTable.ItemId == 'A';
select inventItemGroup
where inventItemGroup.ItemGroupId == inventTable.ItemGroupId;
From the first point of view it seems obvious that the first one with join, since it will result in only one database call and the second will result in two. However, it is not always the case. For example, if records that are being looked up in the second example are cached on the server (or even on the client) there will be no database calls at all, and may be even no client\server calls! The code from the first example will never hit the cache since caching is not supported for the queries with joins.
Actually Dynamics AX caches records by their primary key value. So, if a query has no joins and has primary key in its where clause then it will hit the cache. Otherwise it won't.
select inventTable
join inventItemGroup
where inventItemGroup.ItemGroupId == inventTable.ItemGroupId
&& inventTable.ItemId == 'A';
or
select inventTable
where inventTable.ItemId == 'A';
select inventItemGroup
where inventItemGroup.ItemGroupId == inventTable.ItemGroupId;
From the first point of view it seems obvious that the first one with join, since it will result in only one database call and the second will result in two. However, it is not always the case. For example, if records that are being looked up in the second example are cached on the server (or even on the client) there will be no database calls at all, and may be even no client\server calls! The code from the first example will never hit the cache since caching is not supported for the queries with joins.
Actually Dynamics AX caches records by their primary key value. So, if a query has no joins and has primary key in its where clause then it will hit the cache. Otherwise it won't.
Subscribe to:
Posts (Atom)