Dynamics AX 2012 - 网格控制linkPhysicalTableInstance到TempTable,第一个插入的记录没有出现在Grid中,之后很好

时间:2017-06-30 13:36:47

标签: axapta dynamics-ax-2012

与使用网格控件在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 个答案:

答案 0 :(得分:1)

<强>解决方案

我有一个工作解决方案,我在linkPhysicalTableInstance操作之前在缓冲区引用上运行select语句(delete_from tmptable语句具有相同的效果并且更便宜),尽管它是空的,但它用于初始化缓冲区引用。

然后,linkPhysicalTableInstance操作在第一次运行时成功,因为缓冲区已正确存在 - 写入表单DS的更改现在是持久的,并反映在调用向导的缓冲区引用中。

另外(来自Brandon Weise):

如果你碰巧在你的代码中跳过层,这里有一个小小的问题需要注意。 https://community.dynamics.com/ax/b/dynamicsaxexperience/archive/2016/01/24/2012-unexpected-degeneration-of-insert-recordset-into-tempdb-buffer

我发现对调查有用的技术

(感谢Brandon Weise和MartinDráb的这些)

  1. 似乎使用.linkPhysicalTableInstance(..)来更改与表单数据源关联的基础临时表 已初始化产生了一些奇怪的行为。这似乎是 即使你可以用.getPhysicalTableName()演示也是如此 他们是正确联系的。

    帮助的一种方法是创建表单,以及     调用.init(),但还没有.run()。然后用     .linkPhysicalTableInstance()链接新创建的临时表     将数据源置于外部临时表缓冲区中。在     换句话说,而不是试图移植你已经创建的     将temp表放入表单的数据源,让表单创建temp     表,然后让调用者将临时表移植到自己的表中     缓冲区使用.linkPhysicalTableInstance()。然后插入记录,     然后调用.run()。如有必要,请在表单上调用.executeQuery()     .run()之后的数据源。

    我采用散射枪方法进行打印     表格名称在整个初始化和操作期间,同时     这两个表最终会与同一个表正确链接     名字,他们采取迂回的方式到达那里。

  2. 使用以下命令从SQL Server Management Studio检查临时表的内容:

    设置事务隔离级别read uncommitted;

    从tempdb..t107946_BE044A13A9C24283897CA1B59607CBD2中选择*;

    如果您拥有表名,那么这很容易 .getPhysicalTableName(),但即使你不确切地知道它, 通过一些试验和错误,通常很容易找到它。选择 * 来自tempdb.sys.tables;该表当然以“t”开头 表号。通常它是最近创建的,所以 通过create_date desc排序将其浮动到顶部,但当然 可以有一个池子。

  3. 查看Methods on a Form Data Source通过数据源处理记录时可以使用的方法。