今天聚焦 Manage 系统的「基础数据层」—— 对象Object与记录Record操作这是所有模块的通用能力也是批量数据处理、自定义表单开发的核心。你将掌握分页查询记录、创建关联记录、读取属性卡配置等高频场景附带可直接复用的 C# 完整代码。一、Day5 核心目标查询系统所有对象类型获取 objectId分页查询指定对象的记录列表如物料 / 文档 / 项目读取记录的属性卡配置与字段值创建关联记录如给物料关联文档核心价值脱离前端界面实现数据的批量查询、录入、关联支撑企业级数据同步场景。二、新增核心模型类直接复制using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; namespace ManageApiDemo { // 1. 对象类型模型/api/Object/GetAll 响应 public class ObjectTypeModel { public string Id { get; set; } // objectId如物料101文档102 public string Name { get; set; } // 对象名称如“物料”“文档” public string Description { get; set; } // 对象描述 } // 2. 记录查询请求参数 public class RecordQueryRequest { public string ObjectId { get; set; } // 要查询的对象ID public int PageIndex { get; set; } 1; // 页码从1开始 public int PageSize { get; set; } 50; // 每页条数 public string Filter { get; set; } ; // 筛选条件如 PartNumberPART-001 } // 3. 记录列表响应模型 public class RecordListResponse { public bool Success { get; set; } public string Message { get; set; } public RecordListData Data { get; set; } } public class RecordListData { public int TotalCount { get; set; } // 总记录数 public ListRecordModel Items { get; set; } // 当前页记录 } public class RecordModel { public string RecordId { get; set; } // 记录ID public string ObjectId { get; set; } // 对象ID public Dictionarystring, object Fields { get; set; } // 字段键值对如 PartNumber:PART-001 public string CreateTime { get; set; } // 创建时间 public string Creator { get; set; } // 创建人 } // 4. 属性卡配置模型/api/PropertyCard/GetConfig 响应 public class PropertyCardConfig { public bool Success { get; set; } public string Message { get; set; } public ListFieldGroupModel Data { get; set; } // 字段组列表 } public class FieldGroupModel { public string GroupName { get; set; } // 字段组名称如“基本信息” public ListFieldModel Fields { get; set; } // 组内字段 } public class FieldModel { public string FieldName { get; set; } // 字段名如 PartNumber public string DisplayName { get; set; } // 显示名如 物料编码 public string FieldType { get; set; } // 字段类型如 Text Number public bool IsRequired { get; set; } // 是否必填 } // 5. 创建关联记录请求参数 public class CreateRelationRequest { public string SourceObjectId { get; set; } // 源对象ID如物料101 public string SourceRecordId { get; set; } // 源记录ID public string TargetObjectId { get; set; } // 目标对象ID如文档102 public string TargetRecordId { get; set; } // 目标记录ID public string RelationType { get; set; } Reference; // 关联类型默认Reference } }三、对象与记录操作工具类RecordHelpernamespace ManageApiDemo { public class RecordOperationHelper { private readonly string _baseUrl http://localhost:8888/api/; private readonly HttpClient _httpClient; // 构造函数传入认证Token public RecordOperationHelper(string authToken) { _httpClient new HttpClient(); _httpClient.Timeout TimeSpan.FromSeconds(60); _httpClient.DefaultRequestHeaders.Add(Authorization, authToken); } #region 1. 查询系统所有对象类型 public async TaskListObjectTypeModel GetAllObjectTypesAsync() { try { var url ${_baseUrl}Object/GetAll; var response await _httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var json await response.Content.ReadAsStringAsync(); var objectList JsonConvert.DeserializeObjectListObjectTypeModel(json); Console.WriteLine($共查询到 {objectList.Count} 个对象类型); return objectList; } catch (Exception ex) { Console.WriteLine($查询对象类型异常{ex.Message}); throw; } } #endregion #region 2. 分页查询指定对象的记录 public async TaskRecordListData QueryRecordsAsync(RecordQueryRequest request) { try { var url ${_baseUrl}Record/Query; var response await _httpClient.PostAsJsonAsync(url, request); response.EnsureSuccessStatusCode(); var json await response.Content.ReadAsStringAsync(); var result JsonConvert.DeserializeObjectRecordListResponse(json); if (!result.Success) { throw new Exception($查询记录失败{result.Message}); } Console.WriteLine($查询到 {result.Data.TotalCount} 条记录当前页 {result.Data.Items.Count} 条); return result.Data; } catch (Exception ex) { Console.WriteLine($分页查询记录异常{ex.Message}); throw; } } #endregion #region 3. 读取记录的属性卡配置 public async TaskListFieldGroupModel GetRecordPropertyCardAsync(string objectId, string recordId) { try { var url ${_baseUrl}PropertyCard/GetConfig?objectId{objectId}recordId{recordId}; var response await _httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var json await response.Content.ReadAsStringAsync(); var config JsonConvert.DeserializeObjectPropertyCardConfig(json); if (!config.Success) { throw new Exception($读取属性卡失败{config.Message}); } return config.Data; } catch (Exception ex) { Console.WriteLine($读取属性卡异常{ex.Message}); throw; } } #endregion #region 4. 创建关联记录如物料关联文档 public async Task CreateRecordRelationAsync(CreateRelationRequest request) { try { var url ${_baseUrl}Record/CreateRelation; var response await _httpClient.PostAsJsonAsync(url, request); response.EnsureSuccessStatusCode(); var json await response.Content.ReadAsStringAsync(); var result JsonConvert.DeserializeObjectCommonResponse(json); if (!result.Success) { throw new Exception($创建关联失败{result.Message}); } Console.WriteLine($成功创建关联{request.SourceRecordId} → {request.TargetRecordId}); } catch (Exception ex) { Console.WriteLine($创建关联记录异常{ex.Message}); throw; } } #endregion // 释放资源 public void Dispose() _httpClient?.Dispose(); } }四、完整调用示例核心流程演示namespace ManageApiDemo { class Program { static async Task Main(string[] args) { // 1. 先完成身份认证复用Day1代码 var authHelper new ManageAuthHelper(); string token await authHelper.GetAuthTokenAsync(); // 2. 初始化记录操作工具类 var recordHelper new RecordOperationHelper(token); try { // 场景1查询所有对象类型 var objectTypes await recordHelper.GetAllObjectTypesAsync(); // 打印所有对象类型方便核对objectId foreach (var obj in objectTypes) { Console.WriteLine($对象ID{obj.Id}名称{obj.Name}); } // 场景2分页查询物料记录objectId101 var queryRequest new RecordQueryRequest { ObjectId 101, // 物料对象ID PageIndex 1, PageSize 10, Filter PartNumber Contains PART- // 筛选物料编码包含PART-的记录 }; var recordData await recordHelper.QueryRecordsAsync(queryRequest); // 打印第一条物料记录的字段 if (recordData.Items.Count 0) { var firstRecord recordData.Items[0]; Console.WriteLine($\n第一条物料记录ID{firstRecord.RecordId}); foreach (var field in firstRecord.Fields) { Console.WriteLine(${field.Key}{field.Value}); } // 场景3读取该物料的属性卡配置 var propertyCard await recordHelper.GetRecordPropertyCardAsync(101, firstRecord.RecordId); Console.WriteLine($\n{firstRecord.RecordId} 的属性卡配置); foreach (var group in propertyCard) { Console.WriteLine($字段组{group.GroupName}); foreach (var field in group.Fields) { Console.WriteLine($ {field.DisplayName}{field.FieldName}{field.FieldType}); } } // 场景4创建物料与文档的关联示例 var relationRequest new CreateRelationRequest { SourceObjectId 101, // 源物料 SourceRecordId firstRecord.RecordId, // 源记录ID TargetObjectId 102, // 目标文档 TargetRecordId 你的文档RecordId, // 替换为实际文档RecordId RelationType Reference }; await recordHelper.CreateRecordRelationAsync(relationRequest); } } catch (Exception ex) { Console.WriteLine($记录操作异常{ex.Message}); } finally { recordHelper.Dispose(); authHelper.Dispose(); } Console.ReadKey(); } } }五、高频避坑指南问题现象根因分析解决方案查询记录返回 0 条Filter 筛选条件格式错误筛选条件遵循 SQL 语法如 PartNumberPART-001读取属性卡提示 “无权限”账号无该对象的属性卡查看权限后台给账号分配「属性卡配置」权限创建关联提示 “记录不存在”SourceRecordId/TargetRecordId 错误核对记录 ID确保记录已存在分页查询性能慢PageSize 设置过大如 1000建议 PageSize≤100分批查询六、性能优化建议缓存对象类型Object/GetAll 接口返回的对象类型极少变化建议缓存到本地避免每次调用批量查询优先用 Filter通过 Filter 精准筛选减少返回数据量比 “查所有再本地筛选” 效率高 10 倍字段按需读取可通过添加Fields参数指定只返回需要的字段如FieldsPartNumber,Description减少数据传输。总结对象Object是 Manage 的基础数据类型如物料、文档记录Record是具体的数据条目操作前需先确认objectId分页查询记录是批量数据处理的核心需合理设置PageSize和Filter条件提升性能属性卡配置决定了记录的字段结构读取配置可实现动态表单适配关联记录可实现不同对象间的数据绑定如物料 - 文档、物料 - BOM是系统集成的关键能力。