2025-10-14
SQLSERVER
00

在企业级数据处理中,BOM(物料清单)数据的处理一直是让开发者头疼的问题。特别是当客户要求将复杂的多层嵌套BOM结构展开成一层结构时,如何保证数据准确性、性能优化和业务逻辑的正确实现?

今天就来分享一个真实项目中的SQL Server BOM数据展开解决方案,这个主要是有同事需要用BOM做回冲,说是要某些叶子级物料,用CTE不仅解决了递归展开问题,还巧妙处理了客户的特殊业务需求。

🎯 问题分析:BOM数据展开的核心挑战

业务背景

我们面临的是一个典型的制造业BOM数据处理需求:

  • 多层嵌套结构:BOM数据具有父子层级关系
  • 数量累积计算:子级数量需要根据层级进行累积计算
  • 特殊业务规则:客户要求在特定条件下停止展开
  • 性能要求:大数据量下的高效处理

核心难点

  1. 递归查询复杂度:如何优雅地处理多层递归
  2. 数量计算精度:避免浮点数精度丢失
  3. 业务逻辑集成:将复杂的业务规则融入SQL逻辑
  4. 性能优化:确保大数据量下的查询效率

💡 解决方案:CTE递归查询的最佳实践

🚀 完整解决方案

SQL
-- BOM数据一层展开解决方案 WITH ParentMaterials AS ( -- 第一步:获取所有顶级父物料 SELECT DISTINCT MATNR1, WERKS FROM [sap_bom] WHERE STUFE = 1 AND IsDelete = 0 AND MATNR1 IS NOT NULL AND WERKS IS NOT NULL ), BOM_Expansion AS ( -- 第二步:递归展开BOM结构 -- 递归基础:获取第一层子物料 SELECT b.WERKS, b.MATNR1 AS ParentMaterial, b.MAKTX1 AS ParentDesc, b.IDNRK AS ChildMaterial, b.MAKTX AS ChildDesc, b.MENG AS Quantity, b.DUMPS, b.STUFE, b.BESKZ, 1 AS Level, CAST(b.MENG AS DECIMAL(18,6)) AS AccumulatedQty FROM [sap_bom] b INNER JOIN ParentMaterials p ON b.MATNR1 = p.MATNR1 AND b.WERKS = p.WERKS WHERE b.STUFE = 1 AND b.IsDelete = 0 UNION ALL -- 递归部分:展开下一层 SELECT b.WERKS, e.ParentMaterial, e.ParentDesc, b.IDNRK, b.MAKTX, b.MENG, b.DUMPS, b.STUFE, b.BESKZ, e.Level + 1, CAST(e.AccumulatedQty * b.MENG AS DECIMAL(18,6)) FROM [sap_bom] b INNER JOIN BOM_Expansion e ON b.MATNR1 = e.ChildMaterial AND b.WERKS = e.WERKS WHERE b.STUFE = 1 AND (e.DUMPS = 'x' OR RIGHT(RTRIM(e.ChildMaterial), 1) = 'M' OR e.BESKZ = 'E') AND b.IsDelete = 0 AND e.Level < 10 -- 防止无限递归 -- 🔥 关键业务逻辑:特定条件下停止展开 AND NOT EXISTS ( SELECT 1 FROM [WebAppDb].[dbo].[as_tm_part] sp WHERE sp.part_no = e.ChildMaterial AND sp.site_code = e.WERKS ) ), FinalResult AS ( -- 第三步:过滤最终结果 SELECT WERKS, ParentMaterial, ParentDesc, ChildMaterial, ChildDesc, Quantity, AccumulatedQty, Level, STUFE FROM BOM_Expansion WHERE (DUMPS IS NULL OR DUMPS != 'x') AND RIGHT(RTRIM(ChildMaterial), 1) != 'M' ) SELECT * FROM FinalResult;

image.png

2025-10-14
C#
00

你是否曾经遇到过这样的问题:WPF应用运行一段时间后,内存占用越来越高,最终导致程序卡顿甚至崩溃?特别是在工业级应用中,这种问题更是致命的。今天我们就来彻底解决这个让无数开发者头疼的内存泄漏难题!

🚨 问题分析:事件订阅的隐形杀手

在WPF开发中,最常见的内存泄漏源头就是事件订阅。当你写下这样的代码时:

C#
// 危险代码:容易造成内存泄漏 public class DeviceMonitor { public DeviceMonitor(DeviceService service) { service.DataUpdated += OnDataUpdated; // 强引用陷阱! } private void OnDataUpdated(object sender, EventArgs e) { // 处理逻辑 } }

问题核心:即使 DeviceMonitor 对象不再使用,只要 DeviceService 还在运行,它就会持有对 DeviceMonitor 的强引用,导致垃圾回收器无法回收内存。

在工业监控系统中,这种问题尤其严重:

  • 💀 长时间运行的服务进程
  • 💀 大量的设备数据订阅
  • 💀 频繁创建和销毁的监控界面

💡 解决方案:WeakEventManager救世主登场

WeakEventManager 是WPF提供的弱事件模式实现,它使用弱引用来订阅事件,避免了强引用导致的内存泄漏。

2025-10-13
C#
00

你是否在开发复杂业务流程时遇到过这样的困扰:代码中充斥着大量的if-else判断,业务状态难以维护,流程控制逻辑混乱不堪?特别是在工业控制、游戏开发、工作流系统中,状态管理往往成为项目的技术难点。

**今天,我将通过一个完整的WinForm工业设备控制系统,带你掌握C#状态机编程的精髓。**这不仅是一个编程模式的学习,更是解决复杂业务逻辑的利器。无论你是初学者还是有经验的开发者,这篇文章都会让你对状态机有全新的认识。

🎯 问题分析:为什么需要状态机?

传统代码的痛点

在没有状态机的情况下,我们通常会这样写代码:

C#
// 传统方式:充满条件判断的混乱代码 public void StartMachine() { if (currentStatus == "idle") { if (isInitialized) { currentStatus = "running"; } else { MessageBox.Show("请先初始化设备"); } } else if (currentStatus == "error") { MessageBox.Show("设备故障,无法启动"); } // ... 更多复杂的条件判断 }

这种代码存在以下问题:

  • 维护困难:业务逻辑散落在各个方法中
  • 扩展性差:添加新状态需要修改多处代码
  • 容易出错:状态转换逻辑容易遗漏或冲突
  • 测试复杂:难以覆盖所有状态组合

💡 解决方案:优雅的状态机模式

状态机模式通过状态转换表将复杂的业务逻辑结构化,让代码变得清晰、可维护、易扩展。

🔥 核心设计思想

image.png

2025-10-11
C#
00

你是否曾经为了实现实时通信功能而苦恼?聊天室、在线游戏、实时数据推送...这些场景都离不开WebSocket技术。作为C#开发者,我们经常需要构建WebSocket服务器,但市面上的教程要么过于简单,要么缺乏完整的生产级代码。

今天这篇文章,我将带你从零开始构建一个功能完整、界面精美、代码健壮的WebSocket服务器应用。不仅包含核心的WebSocket处理逻辑,还提供了WinForms可视化管理界面,让你能够实时监控连接状态、管理客户端、广播消息。

本文将解决的核心问题:

  • 如何构建生产级WebSocket服务器
  • 如何处理多客户端并发连接
  • 如何避免UI线程死锁问题
  • 如何优雅地关闭服务器资源

💡 问题分析:WebSocket开发的常见痛点

🔍 技术难点梳理

在C#中开发WebSocket服务器,开发者通常会遇到以下问题:

  1. 并发处理复杂:多个客户端同时连接,如何保证线程安全?
  2. 资源管理困难:连接异常断开时,如何正确释放资源?
  3. UI线程阻塞:异步操作导致界面卡死,用户体验极差
  4. 状态同步问题:客户端连接状态与UI显示不同步

这些问题在实际项目中经常出现,往往让开发者花费大量时间调试。

🛠️ 解决方案架构设计

📐 整体架构

我们采用分层架构设计,将功能模块化:

C#
WebSocketServer/ ├── WebSocketServerCore.cs // 核心服务器逻辑 ├── ClientConnection.cs // 客户端连接管理 ├── Form1.cs // UI逻辑控制 ├── Form1.Designer.cs // 界面设计 └── Program.cs // 程序入口

🔑 核心特性

  • 异步处理:全程使用async/await避免阻塞
  • 线程安全:ConcurrentDictionary管理客户端连接
  • 优雅关闭:支持超时控制和资源释放
  • 实时监控:可视化界面实时显示连接状态

💻 代码实战:核心模块实现

2025-11-11
C#
00

Industrial IoT Era: Are You Still Struggling with Legacy Serial Devices Unable to Connect to Networks?

Are you still experiencing headaches because old serial devices can't directly access the network? Are you working late into the night due to complex protocol conversions? Today, I'll use a complete C# project to teach you step-by-step how to build a high-performance Serial-to-Ethernet converter, transforming traditional devices into smart terminals in seconds!

This is not just a simple conversion tool, but a complete industrial-grade solution featuring multi-client management, asynchronous data processing, real-time status monitoring, and other enterprise-level functions. Whether you're an embedded engineer or a .NET developer, this article will open up a new world of industrial connectivity for you!

🎯 Problem Analysis: Real Pain Points in Industrial Settings

Challenges of Traditional Serial Devices

In factory automation, numerous PLCs, sensors, instruments, and other devices still use RS232/RS485 serial communication. These devices face core problems:

  • Distance Limitations: Serial communication typically doesn't exceed 15 meters
  • Single Point Connection: One serial port can only connect to one device
  • Maintenance Difficulties: Complex wiring, time-consuming troubleshooting
  • Poor Scalability: Cannot directly connect to modern network systems

Shortcomings of Existing Solutions

While serial servers on the market can solve basic needs, they have obvious drawbacks:

  • High Costs: Industrial-grade products often cost thousands of dollars
  • Limited Functionality: Lack flexible data processing capabilities
  • Integration Difficulties: Hard to seamlessly integrate with existing systems

💡 Solution: Smart Converter Built with C#

Core Architecture Design

Our solution adopts a Producer-Consumer pattern, implementing efficient bidirectional data conversion through concurrent queues:

image.png

Technical Highlights

  • Asynchronous Non-blocking: Task-based asynchronous programming model
  • Thread Safety: Using ConcurrentQueue and SemaphoreSlim
  • Multi-client Support: Support multiple network devices connecting simultaneously
  • Real-time Monitoring: Complete status display and logging