问题与在AX 2012中使用带有网格控件的表缓冲区有关,其中第一次添加到表单的tempDB没有实时显示(但是持久性的,后续添加工作正常) .
我在动态社区MSDN的DAX传奇人物MartinDráb和Brandon Weise的帮助下解决了这个问题,但是我发布了SO以防万一它(因为我找不到任何接近的东西),我觉得它不疼社区将在SO上添加更多Dynamics AX内容 . 关于物理表如何链接到tempDB以及它们与表单数据源的关系,还有一些知识 .
原帖:https://community.dynamics.com/ax/f/33/t/225120
问题:
-
我有一个向导,它在运行时生成一个包含网格控件的新表单 .
-
向导将对其临时表之一的引用传递给表单,我在运行时表单的datasource init()方法中使用linkPhysicalTableInstance .
-
GridControl有一个添加新记录按钮,它将记录插入到tmp表引用中 .
-
新记录正确保存到参考临时表,并在关闭并重新打开运行时窗体但在插入后不立即显示在网格中时显示在网格中 .
-
为了增加奇怪性,在创建运行时表单后,插入一个记录然后关闭,后续运行时表单会立即显示新的记录插入,而无需重新打开 . 下面是一些代码片段 .
为什么此行为仅在第一次将数据插入临时表时发生,但对于后续运行时表单显示正常?
创建运行时表单:
args = new Args(formstr(RunTimeFormName));
formRun = classFactory.formRunClass(args);
formRun .parmRuntimeFormsGridTmpDS(sysWizard.ReferenceToWizardsTableTmp()); // Passing a reference for Wizards tmpTable to form
formRun .init();
formRun .run();
formRun .wait();
formRun .detach();
RunTime Form的parmDataSourceMethod:
public void parmRuntimeFormsGridTmpDS(CommentsGridTmp _ReferenceToWizardsTableTmp)
{
ReferenceToWizardsTableTmp = _ReferenceToWizardsTableTmp;
}
DataSource init() method:
public void init()
{
super();
RuntimeFormsGridTmpDS.linkPhysicalTableInstance(ReferenceToWizardsTableTmp);
}
运行时表单的新按钮单击方法:
void clicked()
{
int64 numRows;
;
// Refresh records loaded in grid DS to ensure correct number of records for setting initial index number
// Note: SomeId is passed in Args() record, its passing fine as is the number of rows count - and replacing with a static value has no effect.
select count(RecId) from ReferenceToWizardsTableTmp
where ReferenceToWizardsTableTmp.SomeId == someId;
numRows = ReferenceToWizardsTableTmp.RecId;
ReferenceToWizardsTableTmp.Comment = "Comment " + int642str(numRows + 1);
ReferenceToWizardsTableTmp.Filename = "";
ReferenceToWizardsTableTmp.someId = someId;
ReferenceToWizardsTableTmp.insert();
element .Task(#TaskF5);
// super();
}
因此,如上所述,第一次创建运行时表单并插入记录时,它不会显示 . 重新打开表单将显示插入的数据 . 此外,重新打开表单后,任何插入的新记录都会实时显示在网格中 . 我本来认为它必须与linkToPhysicalTable有关,并且网格字段在哪里寻找要显示的记录......
顺便说一句,如果你有更好的答案或解释,请随时贡献 .
1 回答
Solution
我有一个工作解决方案,我在linkPhysicalTableInstance操作之前在缓冲区引用上运行一个select语句(delete_from tmptable语句具有相同的效果并且更便宜),尽管它是空的,但它用于初始化缓冲区引用 .
然后,linkPhysicalTableInstance操作在第一次运行时成功,因为缓冲区已正确存在 - 写入表单DS的更改现在是持久的,并反映在调用向导的缓冲区引用中 .
In Addition (来自Brandon Weise):
如果您碰巧在您的代码中跳跃层,这里有一个小小的问题需要注意 . https://community.dynamics.com/ax/b/dynamicsaxexperience/archive/2016/01/24/2012-unexpected-degeneration-of-insert-recordset-into-tempdb-buffer
Techniques That I Found Useful for Investigation
(感谢Brandon Weise和MartinDráb这些)
一种帮助的技术是创建表单,并调用.init(),但尚未调用.run() . 然后使用.linkPhysicalTableInstance()将新创建的数据源底层表临时链接到外部临时表缓冲区 . 换句话说,不是试图将已创建的临时表移植到表单的数据源中,而是让表单创建临时表,然后让调用者使用.linkPhysicalTableInstance()将该临时表移植到自己的缓冲区中 . 然后插入记录,然后调用.run() . 如有必要,请在.run()之后在表单数据源上调用.executeQuery() .
我在初始化和操作过程中采用了分散方法来打印表名,虽然这两个表确实最终使用相同的表名正确链接,但它们采用了一种迂回的方式来实现 .
set transaction isolation level read uncommitted;
select * from tempdb..t107946_BE044A13A9C24283897CA1B59607CBD2;
如果你有这个很容易来自.getPhysicalTableName()的表名,但即使你不确切地知道它,通常也很容易找到一些试验和错误 . select * from tempdb.sys.tables;该表当然以“t”和表号开头 . 通常它是最近创建的一个,因此按create_date desc排序会将其浮动到顶部,但当然可以有一个池 .