创建、管理和扩展表映射

已完成

表映射用于定义在一种或多种记录类型上运行的字段和方法。

使用“数据模型与映射”下“应用程序资源管理器”中定义的表映射可以让我们更加安全地捕获记录类型之间的共同点。 此外,使用表映射有助于防止不兼容的记录分配,简化类似表的业务逻辑。

您可以在映射节点中创建表间映射,或使用表上的映射节点和接口类一起创建。 无法为表映射创建扩展,因此,您可以在映射上创建部分映射,在表上创建部分映射,在接口类上创建部分映射。

例如,右键单击映射或激活上下文菜单,即可使用“创建扩展”选项;但是,选中该选项不会引起任何反应。 您可以使用 Visual Studio 创建、管理和扩展表映射。

创建映射

要向项目中添加映射,请转到解决方案资源管理器窗口,右键单击项目或激活上下文菜单,然后选择添加新建项目。 然后,您可以通过设计器和属性窗口修改这些视图。 表映射设计器窗口中包含一个带表映射名称的顶层节点。

下表列出了映射的顶层属性(其他节点的工作原理与它们在表上的工作原理完全相同)。

属性 描述
名称 映射的名称

下表列出了设计器中表映射可用的节点。

节点 描述
字段 要手动创建字段,请右键单击字段节点或激活上下文菜单。 然后,选择新建字段。 您可以在字段上设置扩展数据类型。
字段组 字段组的工作原理与表类似。
映射 用于创建到表的映射以及指向表中映射字段的映射。 通常,要在表上执行映射来实现扩展,然后使用接口类创建特定于表的逻辑。
方法 与表的方法类似;不过,您可以在表映射上创建,而不是在相似的表上使用相同方法。
事件 节点存在但未使用。

管理表映射

需要先构建表映射,才能使用。

扩展表映射

扩展表和类时,无法扩展表映射。 要查找创建扩展菜单项,请右键单击该项目或激活上下文菜单。 选择创建扩展不会触发任何操作。 必须在表到表的映射中设置映射,才能扩展这些表。 此外,如果需要特殊逻辑,则需要使用接口类。

要在表中设置映射,请在“应用程序资源管理器”中找到相应表,然后在设计器中将其打开。 如下图所示,在映射节点中,右键单击表或激活上下文菜单,然后选择新建映射。 然后,输入要使用的映射名称和字段映射。

映射节点的屏幕截图。

如果需要特殊逻辑,请为接口创建一个抽象类。 首先,需要使用前缀为接口 的表映射名称为映射创建一个抽象类,如以下代码示例所示:

public abstract class MyCustVendMapInterface
{
   protected   MyCustVendMap           myCustVendMap;
   private     MyCustVendMapInterface  origInstance;
 
   protected void new()
   {
   }
 
   private void initializeMyCustVendMap(MyCustVendMap _myCustVendMap = myCustVendMap)
   {
       myCustVendMap = _myCustVendMap;
   }
 
   public final MyCustVendMap getMyCustVendMap()
   {
       return myCustVendMap;
   }
 
   /// <summary>
   /// Creates a <c>MyCustVendMapInterface</c> object based on the provided <c>MyCustVendMap</c> record.
   /// </summary>
   /// <param name = "_myCustVendMap">A <c>MyCustVendMap</c> record from which to create a <c>MyCustVendMapInterface</c> instance.</param>
   /// <returns>The instantiated <c>MyCustVendMapInterface</c> object.</returns>
   public static MyCustVendMapInterface createInstance(MyCustVendMap _myCustVendMap)
   {
       SysPluginMetadataCollection metadataCollection = new SysPluginMetadataCollection();
 
       metadataCollection.SetManagedValue(classStr(MyCustVendMapInterface), tableId2Name(_myCustVendMap.tableId));
       MyCustVendMapInterface instance = SysPluginFactory::Instance(identifierStr(Dynamics.AX.Application), classStr(MyCustVendMapInterface), metadataCollection);
 
       if (!instance)
       {
           throw error(strFmt("@SYS19306", funcName()));
       }
 
       instance.initializeMyCustVendMap(_myCustVendMap);
 
       return instance;
   }
 
   /// <summary>
   /// Create a <c>MyCustVendMapInterface</c> object based on the <c>MyCustVendMap</c> orig-record.
   /// </summary>
   /// <returns>
   /// The instantiated <c>MyCustVendMapInterface</c> object.
   /// </returns>
   public final MyCustVendMapInterface origInstance()
   {
       if (!origInstance)
       {
           origInstance = MyCustVendMapInterface::createInstance(this.getMyCustVendMap().orig());
       }
 
       return origInstance;
   }
 
   /// <summary>
   /// Gets module type.
   /// </summary>
   /// <returns>
   /// The <c>ModuleCustVend</c> module type.
   /// </returns>
   /// <exception cref="Exception::Error">
   /// TableId is not associated with any module type.
   /// </exception>
   public ModuleCustVend getModule()
   {
       throw error(strFmt("@SYS19306", funcName()));
   }
 
   /// <summary>
   ///    Initializes the current record by copying all fields from another record.
   /// </summary>
   /// <param name="_bomMap">
   ///    A record that is related to the map of <c>BOMMap</c> type.
   /// </param>
   /// <remarks>
   ///    Both records relate to the map of <c>BOMMap</c> type.The <c>inventDimId</c> value will be copied as
   ///    well.
   /// </remarks>
   [Hookable(false)]
   public final void initFromMyCustVendMap(MyCustVendMap _map)
   {
       myCustVendMap.data(_map);
   }
 
}

对于每个需要特定映射逻辑的表,需要创建一个扩展接口类的新类,如以下代码示例所示:

using System.ComponentModel.Composition;
 
/// <summary>
/// The <c>MyCustVendMapMyCustTable</c> class contains <c>MyCustTable</c> table specific functionality and mapped fields
/// related to the <c>MyCustVendMapInterface</c> table map.
/// </summary>
[ExportMetadata(classStr(MyCustVendMapInterface), tableStr(MyCustVendMap)), ExportAttribute('Dynamics.AX.Application.MyCustVendMapInterface')]
public class MyCustVendMapMyCustTable extends MyCustVendMapInterface
{
   public ModuleCustVend getModule()
   {
       return ModuleCustVend::Cust;
   }
 
}

接下来,需要在映射的方法中启动接口类,如以下代码示例所示:

public class MyCustVendMap extends common
{
   /// <summary>
   /// Create an interface instance.
   /// </summary>
   /// <returns>
   /// The <c>MyCustVendMapInterface</c>.
   /// </returns>
   public MyCustVendMapInterface myCustVendMapInterface()
   {
       return MyCustVendMapInterface::createInstance(this);
   }
 
   /// <summary>
   /// Gets module type.
   /// </summary>
   /// <returns>
   /// The <c>ModuleCustVend</c> module type.
   /// </returns>
   /// <exception cref="Exception::Error">
   /// TableId is not associated with any module type.
   /// </exception>
   public ModuleCustVend getModule()
   {
       return this.custVendTransOpenInterface().getModule();
   }
 
   /// <summary>
   ///    Initializes the current record by copying all fields from another record.
   /// </summary>
   /// <param name="bomMap">
   ///    A record that is related to the map of <c>BOMMap</c> type.
   /// </param>
   /// <remarks>
   ///    Both records relate to the map of <c>BOMMap</c> type.The <c>inventDimId</c> value will be copied as
   ///    well.
   /// </remarks>
   public void initFromMyCustVendMap(MyCustVendMap   _map)
   {
       this.MyCustVendMap::myCustVendMapInterface().initFromMyCustVendMap(_map);
   }
 
}

使用列表中的方法创建映射时,您可以执行扩展,包括:

  • 表扩展,这样就能够使用表的映射。
  • 代码扩展,这样就能够通过以下方式更改映射逻辑:右键单击类或激活上下文菜单,然后选择创建代码扩展(命令链)。 此外,您还可以为方法创建前期事件和后期事件,并在事件处理程序类中加以使用。