工序 BOM 协同系统架构多模块组件

以下是基于现有 MES/ERP 工序 BOM 协同系统架构,完善并扩展的 WinForm 模块化实现代码,涵盖GDI 图表增强、数据维护、多模块联动、本地 SQLite 数据管理等核心能力,保持原有主子结构 / 分节点执行 / 汇总工作台的设计体系:

1. 核心扩展:GDI 图表控件增强(GdiChartEx.cs)

csharp

运行

复制代码
using System;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

/// <summary>
/// 增强版GDI柱状图控件,支持多系列、图例、网格、自定义样式
/// </summary>
public class GdiChartEx : Panel
{
    // 图表配置
    public Color BarColor { get; set; } = Color.CornflowerBlue;
    public Color GridColor { get; set; } = Color.LightGray;
    public Color TextColor { get; set; } = Color.Black;
    public Font LabelFont { get; set; } = new Font("微软雅黑", 9);
    public Font ValueFont { get; set; } = new Font("微软雅黑", 10, FontStyle.Bold);
    
    // 数据源
    private DataTable _dataSource;
    public DataTable DataSource
    {
        get => _dataSource;
        set
        {
            _dataSource = value;
            Invalidate(); // 数据变更重绘
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        if (DataSource == null || DataSource.Rows.Count == 0) return;

        var g = e.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias; // 抗锯齿
        g.Clear(BackColor);

        // 绘制网格背景
        DrawGrid(g);

        // 计算图表区域(留边距)
        int paddingLeft = 80, paddingRight = 20, paddingTop = 30, paddingBottom = 60;
        int chartWidth = ClientSize.Width - paddingLeft - paddingRight;
        int chartHeight = ClientSize.Height - paddingTop - paddingBottom;

        // 计算最大值(用于刻度)
        int maxValue = GetMaxValue();
        float yScale = (float)chartHeight / maxValue;

        // 绘制柱状图
        int barWidth = Math.Min(80, chartWidth / (DataSource.Rows.Count * 2)); // 自适应柱宽
        int x = paddingLeft + (chartWidth - DataSource.Rows.Count * (barWidth + 30)) / 2; // 居中

        foreach (DataRow row in DataSource.Rows)
        {
            string category = row[0].ToString();
            int value = int.Parse(row[1].ToString());
            
            // 柱体坐标计算
            float barHeight = value * yScale;
            float y = paddingTop + (chartHeight - barHeight);

            // 绘制柱体(渐变+边框)
            using (var brush = new LinearGradientBrush(
                new Point(x, (int)y), 
                new Point(x, (int)(y + barHeight)), 
                BarColor, 
                BarColor.Darken(30)))
            {
                g.FillRectangle(brush, x, y, barWidth, barHeight);
                g.DrawRectangle(Pens.Black, x, y, barWidth, barHeight);
            }

            // 绘制数值标签
            var valueText = value.ToString("N0");
            var valueSize = g.MeasureString(valueText, ValueFont);
            g.DrawString(valueText, ValueFont, new SolidBrush(TextColor), 
                x + (barWidth - valueSize.Width) / 2, y - valueSize.Height - 5);

            // 绘制分类标签(旋转45度避免重叠)
            g.TranslateTransform(x + barWidth / 2, ClientSize.Height - paddingBottom + 20);
            g.RotateTransform(-45);
            g.DrawString(category, LabelFont, new SolidBrush(Color.DarkRed), -g.MeasureString(category, LabelFont).Width / 2, 0);
            g.ResetTransform();

            x += barWidth + 30; // 柱间距
        }

        // 绘制图例
        DrawLegend(g);

        // 日志记录
        DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} 增强版柱状图绘制完成 | 数据行数:{DataSource.Rows.Count}\r\n");
    }

    /// <summary>
    /// 绘制网格线
    /// </summary>
    private void DrawGrid(Graphics g)
    {
        int paddingLeft = 80, paddingTop = 30, paddingBottom = 60;
        int chartHeight = ClientSize.Height - paddingTop - paddingBottom;
        int chartWidth = ClientSize.Width - paddingLeft - 20;

        // 横向网格(5等分)
        int gridCount = 5;
        float gridStep = chartHeight / gridCount;
        for (int i = 0; i <= gridCount; i++)
        {
            float y = paddingTop + i * gridStep;
            using (var pen = new Pen(GridColor, 1))
            {
                g.DrawLine(pen, paddingLeft, y, ClientSize.Width - 20, y);
            }
            // 刻度值
            int scaleValue = (int)((chartHeight - i * gridStep) / chartHeight * GetMaxValue());
            g.DrawString(scaleValue.ToString(), LabelFont, Brushes.Gray, paddingLeft - 50, y - 10);
        }

        // 纵向基线
        g.DrawLine(Pens.Black, paddingLeft, paddingTop, paddingLeft, ClientSize.Height - paddingBottom);
        g.DrawLine(Pens.Black, paddingLeft, ClientSize.Height - paddingBottom, ClientSize.Width - 20, ClientSize.Height - paddingBottom);
    }

    /// <summary>
    /// 绘制图例
    /// </summary>
    private void DrawLegend(Graphics g)
    {
        int legendX = ClientSize.Width - 150;
        int legendY = 20;
        // 图例框
        g.FillRectangle(Brushes.White, legendX, legendY, 120, 40);
        g.DrawRectangle(Pens.Black, legendX, legendY, 120, 40);
        // 图例颜色块
        g.FillRectangle(new SolidBrush(BarColor), legendX + 10, legendY + 10, 20, 15);
        g.DrawRectangle(Pens.Black, legendX + 10, legendY + 10, 20, 15);
        // 图例文字
        g.DrawString("计划产量", LabelFont, Brushes.Black, legendX + 35, legendY + 10);
    }

    /// <summary>
    /// 获取数据源最大值(用于刻度计算)
    /// </summary>
    private int GetMaxValue()
    {
        int max = 0;
        foreach (DataRow row in DataSource.Rows)
        {
            int val = int.Parse(row[1].ToString());
            if (val > max) max = val;
        }
        // 向上取整到最近的10的倍数
        return (int)Math.Ceiling(max / 10.0) * 10;
    }

    /// <summary>
    /// 刷新图表
    /// </summary>
    public new void Refresh() => Invalidate();
}

/// <summary>
/// Color扩展方法
/// </summary>
public static class ColorExtensions
{
    public static Color Darken(this Color color, int percent)
    {
        float factor = 1 - percent / 100f;
        return Color.FromArgb(
            color.A,
            (int)(color.R * factor),
            (int)(color.G * factor),
            (int)(color.B * factor));
    }
}

2. 数据维护模块(DataMaintenanceView.cs)

csharp

运行

复制代码
using System;
using System.Data;
using System.Windows.Forms;

/// <summary>
/// 本地数据库数据维护模块(支持8-9组基础数据编辑/新增/删除)
/// </summary>
public static class DataMaintenanceView
{
    // 支持维护的表名
    private static readonly string[] _maintainTables = {
        "WorkStation", "ProcessRoute", "BOM", "WorkTask"
    };

    public static TabPage Create()
    {
        var page = new TabPage("数据维护中心");
        
        // 顶部选择区
        var topPanel = new Panel { Dock = DockStyle.Top, Height = 60 };
        var cboTable = new ComboBox { 
            Dock = DockStyle.Left, Width = 200, 
            DataSource = _maintainTables,
            DropDownStyle = ComboBoxStyle.DropDownList
        };
        var btnRefresh = new Button { Text = "刷新数据", Dock = DockStyle.Left, Width = 100 };
        var btnSave = new Button { Text = "保存修改", Dock = DockStyle.Left, Width = 100 };
        var btnAdd = new Button { Text = "新增行", Dock = DockStyle.Left, Width = 100 };
        var btnDel = new Button { Text = "删除选中", Dock = DockStyle.Left, Width = 100 };
        
        topPanel.Controls.AddRange(new Control[] { cboTable, btnRefresh, btnSave, btnAdd, btnDel });

        // 数据展示区
        var dgvData = new DataGridView { 
            Dock = DockStyle.Fill,
            AllowUserToAddRows = false,
            AllowUserToDeleteRows = false,
            AutoGenerateColumns = true,
            ReadOnly = false
        };

        // 布局组装
        page.Controls.Add(dgvData);
        page.Controls.Add(topPanel);

        // 事件绑定
        cboTable.SelectedIndexChanged += (s, e) => LoadTableData(cboTable.Text, dgvData);
        btnRefresh.Click += (s, e) => LoadTableData(cboTable.Text, dgvData);
        btnAdd.Click += (s, e) => AddNewRow(cboTable.Text, dgvData);
        btnDel.Click += (s, e) => DeleteSelectedRow(cboTable.Text, dgvData);
        btnSave.Click += (s, e) => SaveTableChanges(cboTable.Text, dgvData);

        // 初始加载第一个表
        if (_maintainTables.Length > 0)
            LoadTableData(_maintainTables[0], dgvData);

        return page;
    }

    /// <summary>
    /// 加载指定表数据
    /// </summary>
    private static void LoadTableData(string tableName, DataGridView dgv)
    {
        try
        {
            var dt = LocalDB.Query($"SELECT * FROM {tableName}");
            dgv.DataSource = dt;
            DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} 加载[{tableName}]数据完成,共{dt.Rows.Count}行\r\n");
        }
        catch (Exception ex)
        {
            MessageBox.Show($"加载数据失败:{ex.Message}");
            DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} 加载[{tableName}]数据失败:{ex.Message}\r\n");
        }
    }

    /// <summary>
    /// 新增行
    /// </summary>
    private static void AddNewRow(string tableName, DataGridView dgv)
    {
        if (dgv.DataSource is not DataTable dt) return;
        
        var newRow = dt.NewRow();
        // 自动填充主键(简单自增逻辑)
        var maxId = LocalDB.Query($"SELECT MAX(Id) FROM {tableName}").Rows[0][0];
        newRow["Id"] = maxId == DBNull.Value ? 1 : Convert.ToInt32(maxId) + 1;
        
        dt.Rows.Add(newRow);
        dgv.Refresh();
        DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} [{tableName}]新增空白行\r\n");
    }

    /// <summary>
    /// 删除选中行
    /// </summary>
    private static void DeleteSelectedRow(string tableName, DataGridView dgv)
    {
        if (dgv.CurrentRow == null)
        {
            MessageBox.Show("请选中要删除的行");
            return;
        }

        var id = dgv.CurrentRow.Cells["Id"].Value;
        if (id == DBNull.Value || id == null)
        {
            MessageBox.Show("无效的行ID");
            return;
        }

        try
        {
            LocalDB.Execute($"DELETE FROM {tableName} WHERE Id={id}");
            LoadTableData(tableName, dgv); // 刷新数据
            DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} [{tableName}]删除ID={id}的行\r\n");
            MesEventBus.SendEdit(tableName); // 触发数据编辑事件
        }
        catch (Exception ex)
        {
            MessageBox.Show($"删除失败:{ex.Message}");
        }
    }

    /// <summary>
    /// 保存修改(批量更新)
    /// </summary>
    private static void SaveTableChanges(string tableName, DataGridView dgv)
    {
        if (dgv.DataSource is not DataTable dt) return;

        try
        {
            foreach (DataRow row in dt.Rows)
            {
                if (row.RowState == DataRowState.Modified)
                {
                    // 构建更新SQL(通用逻辑,适配4个核心表)
                    string sql = BuildUpdateSql(tableName, row);
                    LocalDB.Execute(sql);
                    DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} [{tableName}]更新ID={row["Id"]}:{sql}\r\n");
                }
                else if (row.RowState == DataRowState.Added)
                {
                    // 构建插入SQL
                    string sql = BuildInsertSql(tableName, row);
                    LocalDB.Execute(sql);
                    DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} [{tableName}]新增ID={row["Id"]}:{sql}\r\n");
                }
            }

            // 提交后刷新
            dt.AcceptChanges();
            LoadTableData(tableName, dgv);
            MesEventBus.SendEdit(tableName); // 触发数据编辑事件
            MessageBox.Show("数据保存成功!");
        }
        catch (Exception ex)
        {
            MessageBox.Show($"保存失败:{ex.Message}");
            DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} [{tableName}]保存失败:{ex.Message}\r\n");
        }
    }

    /// <summary>
    /// 构建更新SQL
    /// </summary>
    private static string BuildUpdateSql(string tableName, DataRow row)
    {
        return tableName switch
        {
            "WorkStation" => $"UPDATE WorkStation SET Name='{row["Name"]}', Role='{row["Role"]}' WHERE Id={row["Id"]}",
            "ProcessRoute" => $"UPDATE ProcessRoute SET Name='{row["Name"]}', StationId={row["StationId"]}, Sort={row["Sort"]} WHERE Id={row["Id"]}",
            "BOM" => $"UPDATE BOM SET ProductCode='{row["ProductCode"]}', Material='{row["Material"]}', UseQty={row["UseQty"]}, Loss={row["Loss"]} WHERE Id={row["Id"]}",
            "WorkTask" => $"UPDATE WorkTask SET TaskNo='{row["TaskNo"]}', StationId={row["StationId"]}, StationName='{row["StationName"]}', Status='{row["Status"]}', PlanQty={row["PlanQty"]} WHERE Id={row["Id"]}",
            _ => throw new NotSupportedException($"不支持的表:{tableName}")
        };
    }

    /// <summary>
    /// 构建插入SQL
    /// </summary>
    private static string BuildInsertSql(string tableName, DataRow row)
    {
        return tableName switch
        {
            "WorkStation" => $"INSERT INTO WorkStation VALUES({row["Id"]},'{row["Name"]}','{row["Role"]}')",
            "ProcessRoute" => $"INSERT INTO ProcessRoute VALUES({row["Id"]},'{row["Name"]}',{row["StationId"]},{row["Sort"]})",
            "BOM" => $"INSERT INTO BOM VALUES({row["Id"]},'{row["ProductCode"]}','{row["Material"]}',{row["UseQty"]},{row["Loss"]})",
            "WorkTask" => $"INSERT INTO WorkTask VALUES({row["Id"]},'{row["TaskNo"]}',{row["StationId"]},'{row["StationName"]}','{row["Status"]}',{row["PlanQty"]})",
            _ => throw new NotSupportedException($"不支持的表:{tableName}")
        };
    }
}

3. 主窗体扩展(MainForm.cs 完善)

csharp

运行

复制代码
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

public partial class MainForm : Form
{
    private readonly GdiChartEx _chartEx = new GdiChartEx(); // 替换为增强版图表
    private readonly TextBox _logBox = new TextBox();

    public MainForm()
    {
        LocalDB.Init();
        InitializeLayout();
        BindEvents();
        Text = "MES/ERP 工序BOM协同系统(增强版)";
        WindowState = FormWindowState.Maximized;
        
        // 初始化日志框样式
        InitLogBoxStyle();
    }

    private void InitializeLayout()
    {
        var tab = new TabControl { Dock = DockStyle.Fill };
        
        // 原有模块
        tab.TabPages.Add(TaskNodeView.Create());
        tab.TabPages.Add(BomView.Create());
        tab.TabPages.Add(MasterSlaveView.Create());
        tab.TabPages.Add(DashboardView.Create(_logBox));
        
        // 新增模块
        tab.TabPages.Add(ChartViewEx.Create(_chartEx)); // 增强版图表页
        tab.TabPages.Add(DataMaintenanceView.Create()); // 数据维护页

        Controls.Add(tab);
    }

    /// <summary>
    /// 初始化日志框样式
    /// </summary>
    private void InitLogBoxStyle()
    {
        _logBox.Dock = DockStyle.Fill;
        _logBox.Multiline = true;
        _logBox.ReadOnly = true;
        _logBox.BackColor = Color.Black;
        _logBox.ForeColor = Color.Lime;
        _logBox.Font = new Font("Consolas", 10);
        _logBox.ScrollBars = ScrollBars.Vertical;
    }

    private void BindEvents()
    {
        // 任务操作事件
        MesEventBus.OnTaskOperated += (task, station, status) =>
        {
            _logBox.AppendText($"{DateTime.Now:HH:mm:ss} [{station}] 任务[{task}] 状态变更为:{status}\r\n");
        };

        // 数据编辑事件
        MesEventBus.OnDataEdited += (table) =>
        {
            _logBox.AppendText($"{DateTime.Now:HH:mm:ss} 数据表[{table}]发生编辑,触发全系统数据刷新\r\n");
            // 刷新所有关联控件
            TaskNodeView._dgv.DataSource = TaskComponent.GetTasks();
            _chartEx.Refresh();
        };

        // BOM计算事件
        MesEventBus.OnBomCalculated += (product, total) =>
        {
            _logBox.AppendText($"{DateTime.Now:HH:mm:ss} 产品[{product}] BOM计算完成,总需求:{total:N2}\r\n");
        };
    }
}

4. 增强版图表视图(ChartViewEx.cs)

csharp

运行

复制代码
using System;
using System.Windows.Forms;

/// <summary>
/// 增强版图表报表视图
/// </summary>
public static class ChartViewEx
{
    public static TabPage Create(GdiChartEx chart)
    {
        var page = new TabPage("GDI图表报表(增强版)");
        
        // 顶部操作区
        var topPanel = new Panel { Dock = DockStyle.Top, Height = 80 };
        var btnLoadTaskQty = new Button { Text = "加载工站计划产量", Dock = DockStyle.Top, Width = 200 };
        var btnLoadBomQty = new Button { Text = "加载BOM物料需求", Dock = DockStyle.Top, Width = 200 };
        var cboColor = new ComboBox { 
            Dock = DockStyle.Top, 
            Width = 200,
            DropDownStyle = ComboBoxStyle.DropDownList,
            DataSource = new[] { "蓝色", "绿色", "橙色", "紫色" }
        };
        topPanel.Controls.AddRange(new Control[] { btnLoadTaskQty, btnLoadBomQty, cboColor });

        // 图表区
        chart.Dock = DockStyle.Fill;
        chart.BackColor = Color.White;

        // 布局组装
        page.Controls.Add(chart);
        page.Controls.Add(topPanel);

        // 事件绑定
        btnLoadTaskQty.Click += (s, e) =>
        {
            chart.DataSource = LocalDB.Query(@"
                SELECT StationName, SUM(PlanQty) Qty 
                FROM WorkTask 
                GROUP BY StationId, StationName
                ORDER BY SUM(PlanQty) DESC
            ");
            chart.Refresh();
        };

        btnLoadBomQty.Click += (s, e) =>
        {
            chart.DataSource = LocalDB.Query(@"
                SELECT Material, SUM(UseQty*(1+Loss)) TotalNeed 
                FROM BOM 
                WHERE ProductCode='PROD001'
                GROUP BY Material
            ");
            chart.Refresh();
        };

        cboColor.SelectedIndexChanged += (s, e) =>
        {
            chart.BarColor = cboColor.Text switch
            {
                "绿色" => Color.ForestGreen,
                "橙色" => Color.Orange,
                "紫色" => Color.Purple,
                _ => Color.CornflowerBlue
            };
            chart.Refresh();
        };

        // 初始日志
        DashboardView._logBox?.AppendText($"{DateTime.Now:HH:mm:ss} 增强版图表报表初始化完成\r\n");

        return page;
    }
}

5. 关键补充:BOM 模块增强(BomView.cs 完善)

csharp

运行

复制代码
using System;
using System.Data;
using System.Windows.Forms;

public static class BomView
{
    public static TabPage Create()
    {
        var page = new TabPage("BOM物料调配(增强版)");
        
        // 顶部操作区
        var topPanel = new Panel { Dock = DockStyle.Top, Height = 100 };
        var cboProduct = new ComboBox { 
            Dock = DockStyle.Top, 
            Width = 200,
            DropDownStyle = ComboBoxStyle.DropDownList,
            DataSource = new[] { "PROD001", "PROD002" }
        };
        var txtQty = new TextBox { 
            Dock = DockStyle.Top, 
            Width = 200,
            PlaceholderText = "输入计划产量(默认1000)",
            Text = "1000"
        };
        var btnCalc = new Button { Text = "计算物料需求", Dock = DockStyle.Top, Width = 200 };
        topPanel.Controls.AddRange(new Control[] { cboProduct, txtQty, btnCalc });

        // 数据展示区
        var dgv = new DataGridView { Dock = DockStyle.Fill };

        // 布局组装
        page.Controls.Add(dgv);
        page.Controls.Add(topPanel);

        // 事件绑定
        btnCalc.Click += (s, e) =>
        {
            if (!int.TryParse(txtQty.Text, out int planQty) || planQty <= 0)
            {
                MessageBox.Show("请输入有效的计划产量(正整数)");
                return;
            }

            var product = cboProduct.Text;
            var dt = BomComponent.GetBom(product);
            
            // 添加计算列
            if (!dt.Columns.Contains("TotalNeed"))
                dt.Columns.Add("TotalNeed", typeof(decimal));
            if (!dt.Columns.Contains("LossQty"))
                dt.Columns.Add("LossQty", typeof(decimal));

            decimal totalAll = 0;
            foreach (DataRow r in dt.Rows)
            {
                decimal useQty = decimal.Parse(r["UseQty"].ToString());
                decimal loss = decimal.Parse(r["Loss"].ToString());
                
                // 计算净需求+损耗
                decimal lossQty = planQty * useQty * loss;
                decimal total = planQty * useQty + lossQty;
                
                r["LossQty"] = lossQty;
                r["TotalNeed"] = total;
                totalAll += total;
            }

            dgv.DataSource = dt;
            // 格式化列
            dgv.Columns["UseQty"].DefaultCellStyle.Format = "N2";
            dgv.Columns["Loss"].DefaultCellStyle.Format = "P2";
            dgv.Columns["LossQty"].DefaultCellStyle.Format = "N2";
            dgv.Columns["TotalNeed"].DefaultCellStyle.Format = "N2";

            // 触发BOM计算事件
            MesEventBus.SendBom(product, totalAll);
            DashboardView._logBox.AppendText($"{DateTime.Now:HH:mm:ss} 产品[{product}] 产量[{planQty}] BOM计算完成,总物料需求:{totalAll:N2}\r\n");
        };

        return page;
    }
}

核心功能说明

  1. GDI 图表增强

    • 支持抗锯齿、渐变柱体、网格线、图例、旋转标签
    • 自适应柱宽、数值刻度自动计算
    • 支持自定义柱体颜色、字体样式
  2. 数据维护模块

    • 支持 WorkStation/ProcessRoute/BOM/WorkTask 4 大核心表的增删改查
    • 批量保存修改、自动生成主键
    • 触发数据编辑事件,联动刷新全系统数据
  3. BOM 物料计算增强

    • 支持多产品切换、自定义计划产量
    • 拆分净需求 / 损耗量展示,格式化数值显示
    • 触发 BOM 计算事件,日志记录总需求
  4. 模块化架构

    • 主子结构(MasterSlaveView):工站 - 任务联动
    • 分节点执行端(TaskNodeView):任务状态变更
    • 汇总工作台(DashboardView):全局日志
    • 数据维护中心:本地 SQLite 数据编辑
    • GDI 图表报表:多维度数据可视化

部署说明

  1. 将上述代码文件添加到原有 PraticDulTask 项目中
  2. 确保引用System.Data.SQLite(通过 NuGet 安装对应版本)
  3. 调整 MainForm 中 TabPage 的加载逻辑,替换原有 ChartView 为 ChartViewEx
  4. 运行项目后,自动初始化本地 MESData.db 数据库,包含 8-9 组预设测试数据
  5. 支持在「数据维护中心」编辑 / 新增 / 删除基础数据,所有修改实时同步到本地 SQLite 文件

该实现完整覆盖了工序路径管理、BOM 物料需求计算、产线任务执行、GDI 图表可视化、本地数据维护等核心场景,符合 WinForm + 本地文件数据库的轻量化 MES/ERP 协同系统设计目标。

相关推荐
appearappear1 小时前
优雅实现・高并发下大量数据乐观锁批量更新(MySQL 最优实践)
数据库·mysql
TG_yunshuguoji2 小时前
腾讯云代理商:腾讯云CloudBase数据库操作全解析
数据库·人工智能·云计算·腾讯云·cloudbase
学以智用2 小时前
.NET Core 序列化 **超清晰完整版教程**
后端·.net
运维行者_2 小时前
通过Applications Manager的TCP监控确保无缝网络连接
运维·服务器·网络·数据库·人工智能
j7~2 小时前
【MYSQL】视图--详解
数据库·mysql·视图的定义·视图的基本使用·视图的规则和限制
AI玫瑰助手2 小时前
Python函数:局部变量与全局变量的作用域
开发语言·python·信息可视化
我是一颗柠檬2 小时前
【Redis】主从复制Day9
java·数据库·redis·后端
Wenzar_2 小时前
GeoHash+Redis Streams实时围栏系统实战
java·数据库·redis·junit
侯盛鑫2 小时前
理解 RocksDB IngestExternalFile
数据库·后端