news 2026/8/22 11:06:10

C# SOLIDWORKS Manage 二次开发学习 Day5

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C# SOLIDWORKS Manage 二次开发学习 Day5

今天聚焦 Manage 系统的「基础数据层」—— 对象(Object)与记录(Record)操作,这是所有模块的通用能力,也是批量数据处理、自定义表单开发的核心。你将掌握分页查询记录、创建关联记录、读取属性卡配置等高频场景,附带可直接复用的 C# 完整代码。


一、Day5 核心目标

  1. 查询系统所有对象类型(获取 objectId)
  2. 分页查询指定对象的记录列表(如物料 / 文档 / 项目)
  3. 读取记录的属性卡配置与字段值
  4. 创建关联记录(如给物料关联文档)

核心价值:脱离前端界面,实现数据的批量查询、录入、关联,支撑企业级数据同步场景。

二、新增核心模型类(直接复制)

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; } = ""; // 筛选条件(如 "PartNumber='PART-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 List<RecordModel> Items { get; set; } // 当前页记录 } public class RecordModel { public string RecordId { get; set; } // 记录ID public string ObjectId { get; set; } // 对象ID public Dictionary<string, 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 List<FieldGroupModel> Data { get; set; } // 字段组列表 } public class FieldGroupModel { public string GroupName { get; set; } // 字段组名称(如“基本信息”) public List<FieldModel> 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) } }

三、对象与记录操作工具类(RecordHelper)

namespace 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 Task<List<ObjectTypeModel>> GetAllObjectTypesAsync() { try { var url = $"{_baseUrl}Object/GetAll"; var response = await _httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); var objectList = JsonConvert.DeserializeObject<List<ObjectTypeModel>>(json); Console.WriteLine($"共查询到 {objectList.Count} 个对象类型"); return objectList; } catch (Exception ex) { Console.WriteLine($"查询对象类型异常:{ex.Message}"); throw; } } #endregion #region 2. 分页查询指定对象的记录 public async Task<RecordListData> 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.DeserializeObject<RecordListResponse>(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 Task<List<FieldGroupModel>> 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.DeserializeObject<PropertyCardConfig>(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.DeserializeObject<CommonResponse>(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:分页查询物料记录(objectId=101) ========== 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 语法(如 "PartNumber='PART-001'")
读取属性卡提示 “无权限”账号无该对象的属性卡查看权限后台给账号分配「属性卡配置」权限
创建关联提示 “记录不存在”SourceRecordId/TargetRecordId 错误核对记录 ID,确保记录已存在
分页查询性能慢PageSize 设置过大(如 1000+)建议 PageSize≤100,分批查询

六、性能优化建议

  1. 缓存对象类型:Object/GetAll 接口返回的对象类型极少变化,建议缓存到本地,避免每次调用;
  2. 批量查询优先用 Filter:通过 Filter 精准筛选,减少返回数据量,比 “查所有再本地筛选” 效率高 10 倍;
  3. 字段按需读取:可通过添加Fields参数指定只返回需要的字段(如Fields=PartNumber,Description),减少数据传输。

总结

  1. 对象(Object)是 Manage 的基础数据类型(如物料、文档),记录(Record)是具体的数据条目,操作前需先确认objectId
  2. 分页查询记录是批量数据处理的核心,需合理设置PageSizeFilter条件提升性能;
  3. 属性卡配置决定了记录的字段结构,读取配置可实现动态表单适配;
  4. 关联记录可实现不同对象间的数据绑定(如物料 - 文档、物料 - BOM),是系统集成的关键能力。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 16:38:57

DeepSeek LintCode 258 · 地图跳跃 public int mapJump(int[][] arr)

我来为你详细分析 LintCode 258 题「地图跳跃」的解法。 题目理解 题目描述&#xff1a; 给定一个二维数组 arr&#xff0c;每个位置有一个高度值从左上角 (0,0) 出发&#xff0c;要到达右下角 (n-1, m-1)可以向上、下、左、右四个方向移动每次跳跃的高度差不能超过 k&#xff…

作者头像 李华
网站建设 2026/7/14 16:38:56

等保测评命令——Oracle Linux

依据 GB/T 22239-2019《信息安全技术 网络安全等级保护基本要求》等保2.0三级 标准&#xff0c;针对 Oracle Linux 操作系统及 Oracle数据库 给出可直接落地的测评命令清单。覆盖身份鉴别、访问控制、安全审计、入侵防范、恶意代码防范等核心控制点&#xff0c;已在 Oracle Lin…

作者头像 李华
网站建设 2026/7/14 16:38:59

ResNet网络学习

从VGGNet后&#xff0c;CNN结构就从“卷积层&#xff0b;池化层”范式进化为了“卷积块&#xff0b;池化层”范式。 卷积块就是由1层或多层卷积层组成。 这个概念现在基本成为共识。注意&#xff0c;VGGNet提出后&#xff0c;后面网络对卷积层进行了各种“折腾”、“整活”和“…

作者头像 李华
网站建设 2026/7/14 16:38:58

TensorFlow学习笔记:猫狗识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、基础设置与导入数据 import matplotlib.pyplot as plt import numpy as np import os import PIL import tensorflow as tf from tensorflow import ker…

作者头像 李华
网站建设 2026/7/14 16:39:00

稀土抑烟剂: 让PVC燃烧“静默”的秘密

你或许不曾留意&#xff0c;生活中处处可见的PVC材料&#xff0c;正悄然完成一场安全升级。从建筑工地的防护膜、农业温室大棚&#xff0c;到电子产品包装&#xff0c;这种轻便耐用的塑料无处不在。但鲜为人知的是&#xff0c;传统PVC有一个致命短板——遇火即燃&#xff0c;且…

作者头像 李华