AX 365: is it possible to create table relations automatically? Like it was in Ax 2009? - axapta

I have a table FooGroupTable with a primary key FooGroupId of EDT type FooGroupId (and the EDT references FooGroupTable.FooGroupId through table reference)
I also have another table FooTable and I want to make a field FooTable.FooGroupId which references FooGroupTable.FooGroupId: any value that user enters on form into FooTable.FooGroupId should exist in FooGroupTable.FooGroupId.
How to do it in the most efficient way? In Ax 2009 I would just choose EDT and call it day: lookup would work, a check that a value entered in FooTable.FooGroupId exists in FooGroupTable table would be done automatically without me jumping through hoops.
In AX 365 automatic EDT relations are no more.
When I drag'n'drop EDT into fields to make a new field, there is no dialog asking me if I want to make a relation.
I can't drag'n'drop field into relations.
The only way I see is to create table relation manually.
Is there a better way?

TLDR;
In short: no, there does not seem to be a way to create table relations automatically like in AX 2009 based on the extended data type's metadata information.
As the warning in Extended Data Types in the Database states:
Starting in Microsoft Dynamics AX 2012, you can no longer define relations under an EDT element in the AOT.
Note that the extended data types in AX 2012 and D365FO still show a relations node. This is for backwards compatibility to still allow standard extended data types with relations. But for new extended data types, no relations can be defined.
Why?
So why would Microsoft remove this way of defining relations?
Some answers can be found in the Migrating Extended Data Type Relations (White paper). In the introduction, the white paper says:
Table relationships under an EDT
have some disadvantages:
They do not contain the rich relationship metadata, such as cardinality and relation type, that can
be included in relations under a table node.
They can only capture single field relationships, which might not represent the intended — and possibly more intricate — relationship between the tables.
A significant difficulty with having table relations defined under both an EDT and a table is that the
order of relations matters when table relationships are defined in both locations. In such cases, the
kernel will use different algorithms to decide which relationship to examine first, depending on the
context.
The "Add relation?" dialog
The question mentions a dialog when dragging and dropping an extended data type into the fields node of a table asking the user if a relation should be created. This dialog still exists, but compared with earlier versions, it is offered for fewer extended data types (e.g. in AX 2012 it is offered for the ItemId extended data type, in D365FO it is not).
The conditions under which this dialog is offered or not seem to be a combination of the table reference settings on the extended data type and the primary index of the table that is referenced by the extended data type. However, so far, I was only able to find examples where the primary index is set to the default value "Surrogate key" where the dialog is offered. One such an example is the extended data type OMDepartmentRecId, which offers the following dialog in D365FO:
More information
Apart from the previous two links, I would also like to mention a blog article by David Kidder: ReferenceTable & Table References on EDT (images are unfortunately missing and I couldn't find a version of it that has them).
It describes the various combinations of the table reference settings of an extended data type and what the resulting behavior is. It also mentions the "Add relation?" dialog, but at least for D365FO, the description doesn't match the current behavior any more.

Related

When creating a new Dataverse table, why does it come with automatic columns?

I am new to Dataverse, moving from the SQL Server world, and just created my first Dataverse table (Standard table). Upon creation, the table has lots of what I assume are automatically-added columns? These include "Owner", "Status", "Version Number". I come from the SQL Server background where new tables come "empty", with no columns. I do not think I need these automatically-added columns (this is just going to be a small log table that holds datetime, action, etc. columns).
Would it break anything if these automatically-added columns were deleted? Also, if anyone could provide information about why these columns are included, that would help. I have researched these questions online, but found very little. Thank you in advance.
They are standard, out of the box attributes that you can't remove.
You can change the Ownership within the Table Type to "Organization" when creating the table to remove the Owner however the rest are created as part of every table.
There is some high level detail on the docs
https://learn.microsoft.com/en-us/powerapps/maker/data-platform/entity-overview
Dataverse (earlier called as Common Data service) is Dynamics CRM under the hood. It’s a SaaS model CRM online software comes with some basic fundamental components.
When you create a table (entity) it comes with columns (attributes), relationships, views, forms, dashboards, etc.
The UCI model driven app can be made quickly to include these components with all CRUD operations without any code by doing simple configuration and customization.
To support these barebone functionalities - the necessary attributes like name, currency, statecode, statuscode, createdby, createdon, modifiedby, modifiedon and security implication fields like owner, owning business unit, owning team and change tracking & concurrency fields like row version, etc will be created.
You can keep them aside as they are part of platform and do your customization as you need.

Oracle referential Integrity information

Is there a Oracle data dictionary table/view that store the table referential integrity information?
I thought the all_tab_column would show which column is the Pk/Fk.
The documentation has a section on Viewing Constraint Information:
Oracle Database provides the following views that enable you to see constraint definitions on tables and to identify columns that are specified in constraints:
DBA_CONSTRAINTS/ALL_CONSTRAINTS/USER_CONSTRAINTS - DBA view describes all constraint definitions in the database. ALL view describes constraint definitions accessible to current user. USER view describes constraint definitions owned by the current user.
DBA_CONS_COLUMNS/ALL_CONS_COLUMNS/USER_CONS_COLUMNS -
DBA view describes all columns in the database that are specified in constraints. ALL view describes only those columns accessible to current user that are specified in constraints. USER view describes only those columns owned by the current user that are specified in constraints.
You can get more information on those in other sections of the documentation; ALL_CONSTRAINTS and ALL_CONS_COLUMNS.
You haven't said exactly what you're looking for, but this old answer has an example of looking at primary/unique and foreign keys.
Since you tagged your question with SQL Developer, if you view the table from the expanded Connections pane there is a Constraints tab that lists all the constraints on that table. If you select a constraint from the list you can see the columns it applies to. You can use the data modeller to see how tables are related.

How can I determine if a row has changed?

I'm building a data warehouse for a client where one of the sources of data is a Dynamics AX database. For a given AX table I need to determine if a row has been inserted, modified or deleted, so it can be inserted, updated or deleted in the DW.
With regards to detecting a row having been modified, there appears to be two columns in most AX tables I could use for this purpose, ModifiedDateTime and RecVersion. I have two questions related to these columns:
1) Is the ModifiedDateTime column updated each time a row is updated? If so, is this value updated even if someone updates a row directly in the table, outside of an AX application (such as from a tool like SSMS)?
2) Same questions as above for RecVersion. Also, is the number globally unique across the entire database or just unique for the table?
Is there another alternative I'm not aware of to do what I want to do?
You want to use fields RecId and RecVersion, which are available in all business data tables of AX 2012. RecId is a unique value for each record of a table. RecVersion is 1 after a record has been created and is changed to some number other than 1 everytime the record is changed.
ModifiedDateTime is not a good choice, because it is not available on all tables.
Regarding you question if one of those fields is updated when someone modifies data directly in the AX business database: The answer is no and this is one of the reasons why you absolutely never should do such a thing. Honestly, I've seen several customers crash that did this against the explicit recommendations of their implementation partners. Dynamics AX offers several options to integrate data from other systems, use them and don't try to invent your own.
Regarding your question if RecVersion is globally unique: No. You can use a combination of TableId and RecId to uniquelly identify a record in the AX business database.
As I mentioned in my answer to your question How do I get the location for a row in dbo.CUSTTRANS?, AX comes with a data mart and also has some logic on how to update that based on changes in the business data. I'm not familiar with the details of those updates, but it might be worthwhile investigating them to see if you could reuse them for your purposes.
Some parts of AX 2012 use SQL Server Change Tracking under the hood (e.g. AIF).
Change tracking records deleted record as well, which neither ModifiedDateTime nor RecVersion fields can give you.

Entity associations mapping, ORM and Data Modelling approach for a complex task

I'm working on a studio project to try to learn different approaches using Symfony2, Doctrine 2.4.7 as ORM and MySql 5.5 as DB. I've deliberately minimized my question for a better understandability and readability, if you need more details you only have to ask and apologize me if my english is not so good.
To avoid a large discussion due to the title of my question let me synthesize the problem showing a simple and common case (but complex for me because I'm new with doctrine).
The Model:
The User entity (mapped) that stores the user's data
The Category entity (mapped) that stores some categories associated to the User with a ManyToMany BD.
Each User can select one or more Categories.
The Problem:
User categories are near 100.
Many Categories could have a specific associated form.
Each form is composed by common and/or only specific fields (from 1 to 10 fields per category).
The Goal:
Understand what's the most balanced approach for this use case (in terms of flexibility and performances), for create the entities and associations needed to store the data filled by the user (some of these data I wish they were to be searchable).
Some Related References:
Doctrine2 docs
Serialized LOB
Extensible Data Modelling
and many other threads not much relevant...
A Possible Solution:
Create manually a form type for each category with inside the block of related fields (I use this forms as services in DIC and use blocks for the fields I need to reuse on more then one category).
Create a CategoryForm entity with the properties needed to retrieve the name of the form related to the category (useful to the form factory when I build the form) with an association ManyToMany UD with Category and to store the serialized LOB (the data coming from the form and related to the User).
There is a better approach to avoid the serialization of the object in a LOB? (maybe I'm wrong but serialized data are not searchable/indexable in mysql)
Any other solution or reference to a readable resource is welcome!
Well, I will try to answer the question with a simple guess: the category is something shared beetween several users (since you got the many to many).
So, if you want the User's form to be able to set (add/delete or update) Categories assiated to the user, then you should just have acollection of entity widgets related to the Category.
Why do I say that ?
Since your categories are linked to several users, the way you want to treat the relation beetween Categories and Users will cause any update on existing Category from a User's form to be propagated to other Users.
This means that Categories should be created/updated by a single form (modulo your needs). You can then link the Category to the User from User's form.
As far as the number of form of Categories is concerned, there are several parameters to handle:
Are all the Categories validated the same way (to know if you simply need to hide widgets to make the validation work) ?
Do you have a large amount of different types of Categories ?
If yes, are always composed the same way for a given type ?
Give further details if I'm wrong in my initial guess ;)

Dynamically named tables in entity framework queries

I am thinking about ways to manage a table naming issue for an application I'm planning.
Currently there is a table that contains raw materials (approximately 150 rows) and each row has about 20 columns mainly float-value numbers used for calculations. For reference, let's refer to this table as 'materials'.
As these number columns are periodically updated and some users may also wish to create custom versions, I will create a management utility that allows copy/edit of this material table but, crucially it will only allow "save as" under a new table name so that data is never destroyed.
Thus using an automated routine, I'll create 'materials_1", "materials_2" and so on. When a calculation is done in another part of the website, I will store the name of the materials table that was used for the calculation so in future there can be audits done to find where a result has come from.
Now... is it possible for me to do this in an entity framework / unit of work/ repository way (like John Papa's codecamper example) without me having to continually edit the datacontext and add the newly created table names? I can't see how I can pass in a variable to the repository interface that contains the specific table name, which will always be a 'materials' entity even though the physical table name varies?

Resources