icCube parent/child sort view id = parent_id - iccube

I have a child/parent view where the child and parent are both strings. When I try to deploy the cube I get the following error:
Parent/Child View 'AreaSort' without a single root member, at least one root member is mandatory. A Root member is defined with PARENT_ID = NULL or PARENT_ID = ID.
However, I do have PARENT_ID = ID for the root member. If instead I set PARENT_ID = NULL then everything deploys properly.

It's an issue with the sorting view that does not support this case (parentId = id ). It's fixed and will be part of the following icCube version ( next to 6.0.3 ).

Related

Datasource Paging Issue (Revised Again)

See Datasource Paging Issue (Revised)
for the original question.
Markus, you were kind enough to help with out with the issue of incorporating a record count into a query using a calculated datasource. I have a search form with 15 widgets - a mix of date ranges, dropdowns, text values and ._contains, ._equals, ._greaterThanOrEquals, ._lessThanOrEquals, etc.
I have tested this extensively against mySQL SQL code and it works fine.
I have now added a 16th parameter PropertyNames, which is a list with binding #datasource.query.filters.Property.PropertyName._in and Options blank. The widget on the form is hidden because it is only used for additional filtering.
Logic such as the following is used, such that a particular logged-in user can only view their own properties. So if they perform a search and the Property is not specified we do:-
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = params.param_PropertyNames;
}
The record count (records.length) is correct, and if I for loop through the array of records the record set is correct.
However, on the results page the table displays a larger resultset which omits the PropertyNames filter. So if I was to search on Status 'Open' (mySQL results 50) and then I add a single value ['Property Name London SW45'] for params.param_PropertyNames the record count is 6, the records array is 6 but the datasource display is 50. So the datasource is not filtering on the property array.
Initially I tried without adding the additional parameter and form widget and just using code such as
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = properties; // an array of
properties to filter out
}
But this didn't work, hence the idea of adding a form widget and an additional parameter to the calculated recordcount datasource.
If I inspect at query.parameters then I see:-
"param_Status": "Open",
"param_PropertyNames": ["Property Name London SW45"],
If I inspect query.filters:-
name=param_Status, value=Open
name=param_PropertyNames, value=[]}]}
It looks as though the filter isn't set. Even hard coding
ds.filters.Property.PropertyName._in = ['Property Name London SW45'],
I get the same reuslt.
Have you got any idea what would be causing this issue and what I can do for a workaround ?
Using a server side solution I would suggest editing both your SQL datasource query script (server side) that is supposed to filter by this property list and including the same code in your server side script for your calculated Count datasource. The code would look something like this, not knowing your exact details:
var subquery = app.models.Directory.newQuery();
subquery.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
subquery.prefetch.Property._add();
var results = subquery.run();
if(!results[0].CanViewAllRecords) {
query.filters.Property.PropertyName._in = results[0].Property.map(function(i) {return i.PropertyName;});
}
By adding this code you are filtering your directory by your current user and prefetching the Property relation table, then you set the filter only if your user canviewallRecords is false and use JS map function to create an array of the PropertyName field in the Property table. As I stated, your code may not be exactly the same depending on how you have to retrieve your user canviewallrecords property and then of course I don't know your relation between user and Property table either, is it one-to-many or other. But this should give you an idea how to implement this on server side.

Getting the latest ID of an auto increment when using unit of work

I have two tables. One is the product (the basic table) and the other table is a product class (which has specific properties for the product class). I am keeping the ID of the product (from the product table) inside the specific table. The problem comes when I try to use unit of work. I have to get the ID of the added item in the product (basic) table but since I haven't commited the transaction, the ID doesn't exist (since I am using auto increment in my database). When I wasn't using unit of work I had the advantage of objects in C#, that they are reference types and I could easy get out the ID from the newly added product item (product table) right after I had saved it to the table with (context.SaveChanges() method) but now.... Any ideas?
PS: MVC
Do something like bellow code:
db.MyJobContext.Add(job);
db.SaveChanges();
//get inserted Id
int JobId = job.Id;
var JobProvObj = new JobProvRel();
JobProvObj.JobId = JobId;
foreach (int P_id in Provinces)
{
JobProvObj.ProvinceId = P_id;
db.MyJobProvRelContext.Add(JobProvObj);
db.SaveChanges();
}

How to use SQL Server 2008 stored procedure in asp.net mvc

I have created a simple stored procedure in SQL Server 2008 as:
CREATE PROCEDURE viewPosts
AS
SELECT * FROM dbo.Post
Now, I have no idea how to use it in controller's action, I have a database object which is:
entities db = new entities();
Kindly tell me how to use stored procedure with this database object in Entity Framework.
For Details check this link:
http://www.entityframeworktutorial.net/data-read-using-stored-procedure.aspx
Hope this will help you.
See article about 30% in:
In the designer, right click on the entity and select Stored Procedure mapping.
Click and then click the drop down arrow that appears. This exposes the list of all Functions found in the DB metadata.
Select Procedure from the list. The designer will do its best job of matching the stored procedure’s parameters with the entity properties using the names. In this case, since all of the property names match the parameter names, it maps every one correctly so you don’t need to make any changes. Note: The designer is not able to automatically detect the name of the field being returned.
Under the Result Column Bindings section, click and enter variable name. The designer should automatically select the entity key property for this final mapping.
The following code is what I use to initialize the stored procedure, then obtain the result into variable returnedResult, which in this case is the record id of a newly created record.
SqlParameter paramResult = new SqlParameter("#Result", -1);
paramResult.Direction = System.Data.ParameterDirection.Output;
var addParameters = new List<SqlParameter>
{
new SqlParameter("#JobID", EvalModel.JobID),
new SqlParameter("#SafetyEvaluator", EvalModel.SafetyEvaluator),
new SqlParameter("#EvaluationGuid", EvalModel.EvaluationGuid),
new SqlParameter("#EvalType", EvalModel.EvalType),
new SqlParameter("#Completion", EvalModel.Completion),
new SqlParameter("#ManPower", EvalModel.ManPower),
new SqlParameter("#EDate", EvalModel.EDate),
new SqlParameter("#CreateDate", EvalModel.CreateDate),
new SqlParameter("#Deficiency", EvalModel.Deficiency.HasValue ? EvalModel.Deficiency.Value : 0),
new SqlParameter("#DeficiencyComment", EvalModel.DeficiencyComment != null ? EvalModel.DeficiencyComment : ""),
new SqlParameter("#Traffic", EvalModel.Traffic.HasValue ? EvalModel.Traffic.Value : 0),
paramResult
};
// Stored procedure name is AddEval
context.Database.ExecuteSqlCommand("AddEval #JobID, #SafetyEvaluator, #EvaluationGuid, #EvalType, #Completion, #ManPower, #EDate, #CreateDate, #Deficiency, #DeficiencyComment, #Traffic, #Result OUTPUT", addParameters.ToArray());
var returnedResult = paramResult.Value;
NewEvaluationID = Convert.ToInt32(returnedResult);

App Engine emulated datastore - strange observation

I was experimenting with 'datastore' on my machine. Using this code.
Key parentKey = KeyFactory.createKey("parent", "parentId");
try {
// Entity parent = new Entity("parent", "parentId");
// parent.setUnindexedProperty("property1", "value1");
// ds.put(parent);
Entity savedParent = ds.get(parentKey);
// savedParent.setUnindexedProperty("property1", "value3");
// ds.put(savedParent);
// Entity child = new Entity("child", "childId", savedParent.getKey());
Entity child = ds.get(KeyFactory.createKey(savedParent.getKey(), "child", "childId"));
child.setUnindexedProperty("property1", "val2");
ds.put(child);
// logger.info("Saved child.");
} catch (EntityNotFoundException e) {
throw new RuntimeException(e);
}
First I saved parent entity and set property on it to "value2" then I added a child entity with property val1. Then I updated parent property to value3. Then I updated property on child to val2.
Then I found out in the admin console, that value of the property on the parent is back to value2. I repeated it again with the same result. Am I missing something? Or is this some kind of bug?
I suppose, this is manifestation of eventual consistency, right? I run each step in a new JVM instance, thinking that values must have been stored at the time I switched it off:-. Contradicting common sense, but correct in terms of emulation of eventual consistency....

How to find a table name by ID in Dynamics AX

Each table in the AOT has an ID, how can I discover the table name given an ID?
Looking at the SQL dictironary is really the correct method.
Search for the line with the FieldId equal to 0.
Using TSQL this will tell the name of the table for tableid 505
select NAME
from SQLDICTIONARY
where TABLEID = 505
and FIELDID = 0
From X++, use the tableId2Name function.
From the GUI, choose Tools/Development tools/Application objects/Application objects and filter for a recordType of TableInternalHeader and a parentId of the table id you are looking for.
Or in the AOT, right click on Tables and choose Find. On the Name & Location tab, set Search to All nodes. On the Properties tab click Selected next to ID and fill in the table id in the Range field.
I dont'know if this is your answer,
if you want to give the TableName with his ID, you can use
the method:
str tableId2Name(int _tableid)
For example:
If YourTable has ID :123456 ;
use method
tableId2PName(123456)
will return the str name YourTable.
info(strFmt("%1" , tableId2PName(123456))); -> VideoStamp the name.
I used the info in
https://msdn.microsoft.com/en-us/library/aa498759.aspx
I hope to useful , greetings!
If you need AX system table name you can use tableId2name or DictTable.name method.
If you need SQL table name you shoud use DictTable.name method with first argument of DbBackend::Sql
Example:
print new DictTable(tableNum(DirPartyTable)).name(DbBackend::Sql);
print new DictTable(tableNum(OMOperatingUnit)).name(DbBackend::Sql);
pause;
// result:
// DIRPARTYTABLE
// DIRPARTYTABLE
Or you can try:
select Name, AxId
from MicrosoftDynamicsAX_model.dbo.ModelElement (nolock)
where ElementType = 44
order by AxId
In the AOT, go to the System Documentation node.
In the Tables node, find SqlDictionary and open it with the table browser.
Filter the column TabId with your ID.
In the AOT, go to the System Documentation node. In the Tables node, find SqlDictionary and right click and open it with the table browser. Filter the column TabId with your ID and fieldid == 0, his will give you the name of the table.
Easiest way:
Create a project (not necessary but easier to delete later)
Add a new view to your project
Add the data source SqlSyncInfo
Drag the fields ID, MessageType, SyncTable, TableName, etc to field
Open the view
It provides all the table names and their respective IDs. Just filter what you want. If you know the table ID, search for that. If you know the table name, search for that.

Resources