You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用C#或X++动态读取D365运营AOT中的表名与属性

动态读取Dynamics 365 Finance & Operations AOT中的表名称及属性(C#和X++实现)

我来帮你梳理下用X++和C#动态读取D365 F&O AOT中表名称及属性的具体实现方法,这俩场景我都做过不少,直接上干货:

X++ 实现方案

X++作为D365 F&O的原生开发语言,直接访问AOT元数据是最直接高效的,核心就是利用SysDictTable这个系统类来遍历表并获取属性。

示例代码

static void readAOTTablesAndAttributes(Args _args)
{
    SysDictTable      sysDictTable;
    TableId           tableId;
    DictField         dictField;
    int               fieldIdx;

    // 遍历所有注册的表ID范围
    for (tableId = tablenum(FirstTable); tableId <= tablenum(LastTable); tableId++)
    {
        sysDictTable = SysDictTable::newTableId(tableId);
        // 可选:排除系统表,只保留自定义/业务表
        if (sysDictTable && !sysDictTable.isSystemTable())
        {
            info(strFmt("表名称: %1, 显示标签: %2, 表ID: %3", 
                sysDictTable.name(), 
                sysDictTable.label(), 
                tableId));

            // 遍历表的所有字段,获取字段属性
            for (fieldIdx = 1; fieldIdx <= sysDictTable.fieldCnt(); fieldIdx++)
            {
                dictField = sysDictTable.fieldObject(fieldIdx);
                if (dictField)
                {
                    info(strFmt("  字段名: %1, 显示标签: %2, 数据类型: %3", 
                        dictField.name(), 
                        dictField.label(), 
                        enum2Str(dictField.typeId())));
                }
            }
        }
    }
}

关键细节

  • SysDictTable封装了表的所有元数据,通过表ID实例化后,能获取表的名称、显示标签、表组(比如临时表、普通表)、字段数量等信息。
  • 如果需要过滤特定类型的表,比如只看临时表,可以用sysDictTable.isTmpTable();或者通过sysDictTable.tableGroup()判断表所属的分组。
  • 字段的更多属性(比如是否必填、字段长度)可以通过DictField的其他方法获取,比如dictField.mandatory()dictField.stringSize()

C# 实现方案

C#作为外部语言,没法直接访问D365的AOT,得通过官方提供的API来获取元数据。最通用的方式是OData Metadata API,不管是云环境还是内部部署都能兼容,而且配置简单。

方法1:解析OData Metadata文档

D365的OData服务提供了$metadata端点,返回的XML文档包含了所有实体(对应AOT中的表)的完整元数据,我们只需要解析这个XML就能拿到表和字段信息。

示例代码

using System;
using System.Net.Http;
using System.Xml.Linq;
using System.Threading.Tasks;

class D365TableMetadataReader
{
    static async Task Main(string[] args)
    {
        // 替换成你的D365环境地址、账号密码
        string d365BaseUrl = "https://your-d365-environment-url.cloudax.dynamics.com/data/";
        string metadataUrl = $"{d365BaseUrl}$metadata";
        string username = "your-account@domain.com";
        string password = "your-password";

        using (HttpClient client = new HttpClient())
        {
            // 配置身份验证:生产环境建议用OAuth 2.0,这里用基本认证做演示
            var authBytes = System.Text.Encoding.ASCII.GetBytes($"{username}:{password}");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(
                "Basic", Convert.ToBase64String(authBytes));

            // 获取元数据文档
            var response = await client.GetAsync(metadataUrl);
            response.EnsureSuccessStatusCode();
            string metadataXml = await response.Content.ReadAsStringAsync();

            // 解析XML提取表和字段信息
            XDocument doc = XDocument.Parse(metadataXml);
            XNamespace edmNs = "http://docs.oasis-open.org/odata/ns/edm";

            foreach (var entityType in doc.Descendants(edmNs + "EntityType"))
            {
                string tableName = entityType.Attribute("Name").Value;
                Console.WriteLine($"表名称: {tableName}");

                // 遍历字段属性
                foreach (var property in entityType.Descendants(edmNs + "Property"))
                {
                    string fieldName = property.Attribute("Name").Value;
                    string fieldType = property.Attribute("Type").Value;
                    Console.WriteLine($"  字段名: {fieldName}, 数据类型: {fieldType}");
                }
            }
        }
    }
}

方法2:调用EntityDefinitions API(获取更详细属性)

如果需要获取表的显示标签、描述等更丰富的属性,可以直接调用EntityDefinitions API,返回的JSON包含更完整的元数据:

// 示例请求地址,可通过$filter过滤特定表
string entityDefUrl = $"{d365BaseUrl}EntityDefinitions?$filter=SchemaName eq 'CustTable'";
// 发送GET请求后解析JSON即可拿到表的标签、描述等信息

关键细节

  • 生产环境绝对不要用基本认证,一定要用Azure AD OAuth 2.0,需要在Azure AD中注册应用并配置D365的权限。
  • OData中的EntityType对应AOT中的表,Property对应表的字段,还能获取主键、导航属性等关联信息。
  • 如果是内部部署环境,也可以使用Dynamics AX Business Connector,但这个方式在云环境中已经被淘汰,优先用OData方案。

内容的提问来源于stack exchange,提问作者karthikeyan

火山引擎 最新活动