关于 entityframework 提示错误信息-> update与某表foreign key产生冲突解决办法

“UPDATE语句冲突与外键约束\” FK_PATIENTS_DropdownCounty \”。该冲突发生于数据库\“**** \”,表\“dbo.DropdownCounty \”,列“县”

今天在做服务器的时候,出现了这样的问题,当我使用entityframework创建的两个表中添加了一对多的关联,举例t1与t2,t1为一,t2为多,假设t1是公会表,t2是公会成员表,也就是说,一个公会有多个成员,一个成员只属于一个公会,当我想要操作数据库,将某个公会表中的成员踢出的时候,产生了题目的错误,当时我的想法是这样的

首先根据传过来的id找到对应的公会id和角色id,然后分别在这两个表中将两个记录删除
犯得错误1:对数据库操作的语句重复,两个操作语句都删除的是同一个表的记录。

修改后第二次尝试:首先删除 成员表中的成员记录,然后再删除公会表中对应的成员记录
出现提示错误,我的表是这样的
在这里插入图片描述
TGuildMember->GuildId 是TGuild的一个外键 由于外键是可以为空的,但是主键不能为空,(他是一个表的唯一标识)所以要先删除外键所在表中的记录,然后再删除对应主键所在表的记录,也就是先TGuildMember再TGuild。

说的可能不对,但是我的确是这样解决的,以后遇到类似的事情还会继续更新这篇文章,如有错误请,大佬们多多指教/膜拜。

使用C#和MySQL开发仓库管理系统的方法 一、系统架构设计 技术栈选择: 前端:WinForms或WPF(桌面应用) 后端:C# .NET Framework/.NET Core 数据库:MySQL 8.0+ ORM框架:Entity Framework Core或Dapper(推荐Dapper轻量高效)1 基础模块划分: mermaid graph TD A[仓库管理系统] --> B[基础数据管理] A --> C[入库管理] A --> D[出库管理] A --> E[库存管理] A --> F[报统计] 二、数据库设计(MySQL) SQL -- 创建数据库 CREATE DATABASE WarehouseDB CHARACTER SET utf8mb4; -- 货物 CREATE TABLE Products ( ProductID INT AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Category VARCHAR(50), UnitPrice DECIMAL(10,2), StockQuantity INT DEFAULT 0 ); -- 入库单 CREATE TABLE InboundOrders ( OrderID INT AUTO_INCREMENT PRIMARY KEY, ProductID INT NOT NULL, Quantity INT NOT NULL, InboundDate DATETIME DEFAULT CURRENT_TIMESTAMP, Operator VARCHAR(50), FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ); -- 出库单 CREATE TABLE OutboundOrders ( OrderID INT AUTO_INCREMENT PRIMARY KEY, ProductID INT NOT NULL, Quantity INT NOT NULL, OutboundDate DATETIME DEFAULT CURRENT_TIMESTAMP, Recipient VARCHAR(100), FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ); 三、C#核心功能实现 数据库连接(使用Dapper): C# using MySql.Data.MySqlClient; using Dapper; public class DbHelper { private static string _connStr = "Server=localhost;Database=WarehouseDB;Uid=root;Pwd=123456;"; public static MySqlConnection GetConnection() => new MySqlConnection(_connStr); } 入库操作(带事务处理): C# public void AddInboundOrder(int productId, int quantity, string operatorName) { using (var conn = DbHelper.GetConnection()) { conn.Open(); using (var transaction = conn.BeginTransaction()) { try { // 添加入库记录 conn.Execute( @"INSERT INTO InboundOrders(ProductID, Quantity, Operator) VALUES (@ProductID, @Quantity, @Operator)", new { ProductID = productId, Quantity = quantity, Operator = operatorName }, transaction ); // 更新库存 conn.Execute( @"UPDATE Products SET StockQuantity = StockQuantity + @Quantity WHERE ProductID = @ProductID", new { ProductID = productId, Quantity = quantity }, transaction ); transaction.Commit(); } catch { transaction.Rollback(); throw; } } } } 库存预警功能: C# public List<Product> GetLowStockProducts(int threshold = 10) { using (var conn = DbHelper.GetConnection()) { return conn.Query<Product>( "SELECT * FROM Products WHERE StockQuantity < @Threshold", new { Threshold = threshold } ).ToList(); } } 四、界面开发建议(WinForms) C# // 主窗体加载库存数据 private void MainForm_Load(object sender, EventArgs e) { dataGridView1.DataSource = new WarehouseService().GetAllProducts(); } // 入库按钮事件 private void btnInbound_Click(object sender, EventArgs e) { var service = new WarehouseService(); service.AddInboundOrder( selectedProductId, int.Parse(txtQuantity.Text), txtOperator.Text ); MessageBox.Show("入库成功!"); } 五、安全优化 安全措施: 使用参数化SQL防止注入攻击 数据库连接字符串加密 操作日志记录(创建OperationLogs) 性能优化: 为ProductID创建索引 使用MySQL连接池 批量操作时使用BulkInsert 六、部署流程 安装MySQL服务器并创建数据库 发布C#应用: Bash dotnet publish -c Release -r win-x64 配置appsettings.json中的数据库连接字符串 使用Inno Setup制作安装包
最新发布
12-24
<think>我们正在开发一个基于C#和MySQL的仓库管理系统。根据之前的对话,用户已经了解了如何创建C#项目并添加MySQL.Data包。现在用户希望了解从架构设计到部署的全流程方法及示例代码。 根据引用内容,我们得知: 1. 系统采用三层架构(UI/BLL/DAL) 2. 使用ADO.NET进行数据交互(但根据引用[2],也可以使用Entity Framework,不过用户之前的操作是安装MySql.Data,所以这里我们主要使用ADO.NET,但也可以考虑使用Dapper作为ORM) 3. 需要实现商品管理、库存监控、出入库记录、报统计等功能 4. 强调异常处理、事务安全权限控制 因此,我们将按照以下步骤进行: 1. 系统架构设计(三层架构) 2. 数据库设计(根据仓库管理系统的需求设计结构) 3. 搭建数据访问层(DAL) 4. 搭建业务逻辑层(BLL) 5. 搭建用户界面层(UI,这里以WinForms为例) 6. 实现核心功能(商品管理、出入库等) 7. 部署发布 由于内容较多,我们将分步骤详细说明,并给出关键代码示例。 ### 1. 系统架构设计 三层架构: - **DAL(数据访问层)**:负责数据库交互,执行SQL语句- **BLL(业务逻辑层)**:处理业务逻辑,调用DAL的方法,并处理事务。 - **UI(示层)**:WinForms界面,调用BLL的方法。 项目结构(解决方案中的项目): - `WarehouseManagement.DAL`:类库项目 - `WarehouseManagement.BLL`:类库项目 - `WarehouseManagement.WinForms`:Windows Forms应用项目 另外,可以添加一个公共类库`WarehouseManagement.Common`,用于存放公共类(如数据库连接帮助类、实体类等)。但为了简化,我们可以将实体类放在DAL中。 ### 2. 数据库设计 根据仓库管理系统的核心功能,设计以下: #### 2.1 结构设计 - **产品(Products)**:存储产品信息 ```sql CREATE TABLE Products ( ProductID INT AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Category VARCHAR(50), UnitPrice DECIMAL(10,2) NOT NULL, StockQuantity INT NOT NULL DEFAULT 0, Description TEXT ); ``` - **入库(InboundOrders)**:记录入库信息 ```sql CREATE TABLE InboundOrders ( InboundID INT AUTO_INCREMENT PRIMARY KEY, ProductID INT NOT NULL, Quantity INT NOT NULL, InboundDate DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ); ``` - **出库(OutboundOrders)**:记录出库信息 ```sql CREATE TABLE OutboundOrders ( OutboundID INT AUTO_INCREMENT PRIMARY KEY, ProductID INT NOT NULL, Quantity INT NOT NULL, OutboundDate DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ); ``` - **用户(Users)**:系统用户(用于登录和权限控制) ```sql CREATE TABLE Users ( UserID INT AUTO_INCREMENT PRIMARY KEY, Username VARCHAR(50) NOT NULL UNIQUE, Password VARCHAR(100) NOT NULL, -- 存储哈希后的密码 Role VARCHAR(20) NOT NULL -- 例如:Admin, Operator ); ``` #### 2.2 初始化数据 插入一些测试数据。 ### 3. 搭建数据访问层(DAL) 创建类库项目`WarehouseManagement.DAL`,并添加对`MySql.Data`的引用。 #### 3.1 数据库帮助类(DbHelper.cs) 用于获取数据库连接字符串和创建连接对象。 ```csharp using MySql.Data.MySqlClient; using System.IO; using Microsoft.Extensions.Configuration; namespace WarehouseManagement.DAL { public static class DbHelper { private static string _connectionString; static DbHelper() { // 从appsettings.json读取连接字符串 var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); var configuration = builder.Build(); _connectionString = configuration.GetConnectionString("WarehouseDB"); } public static MySqlConnection GetConnection() { return new MySqlConnection(_connectionString); } } } ``` #### 3.2 实体类(在DAL项目中创建Models文件夹) - `Product.cs` ```csharp namespace WarehouseManagement.DAL.Models { public class Product { public int ProductID { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal UnitPrice { get; set; } public int StockQuantity { get; set; } public string Description { get; set; } } } ``` 同样创建`InboundOrder`, `OutboundOrder`, `User`等实体类。 #### 3.3 数据访问类(例如:ProductDAL.cs) 使用ADO.NET进行数据库操作。 ```csharp using MySql.Data.MySqlClient; using System.Collections.Generic; using WarehouseManagement.DAL.Models; namespace WarehouseManagement.DAL { public class ProductDAL { // 获取所有产品 public List<Product> GetAllProducts() { List<Product> products = new List<Product>(); using (MySqlConnection conn = DbHelper.GetConnection()) { conn.Open(); string sql = "SELECT ProductID, Name, Category, UnitPrice, StockQuantity, Description FROM Products"; MySqlCommand cmd = new MySqlCommand(sql, conn); using (MySqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { products.Add(new Product { ProductID = reader.GetInt32("ProductID"), Name = reader.GetString("Name"), Category = reader.GetString("Category"), UnitPrice = reader.GetDecimal("UnitPrice"), StockQuantity = reader.GetInt32("StockQuantity"), Description = reader.GetString("Description") }); } } } return products; } // 添加产品 public int AddProduct(Product product) { using (MySqlConnection conn = DbHelper.GetConnection()) { conn.Open(); string sql = "INSERT INTO Products (Name, Category, UnitPrice, StockQuantity, Description) " + "VALUES (@Name, @Category, @UnitPrice, @StockQuantity, @Description)"; MySqlCommand cmd = new MySqlCommand(sql, conn); cmd.Parameters.AddWithValue("@Name", product.Name); cmd.Parameters.AddWithValue("@Category", product.Category); cmd.Parameters.AddWithValue("@UnitPrice", product.UnitPrice); cmd.Parameters.AddWithValue("@StockQuantity", product.StockQuantity); cmd.Parameters.AddWithValue("@Description", product.Description); return cmd.ExecuteNonQuery(); } } // 更新产品 public int UpdateProduct(Product product) { // 类似AddProduct,使用UPDATE语句 } // 删除产品 public int DeleteProduct(int productId) { // 注意:如果产品有出入库记录,需要先处理外键约束(或者使用级联删除,但通常建议先删除关联记录) // 这里我们假设没有外键约束,或者已经处理 using (MySqlConnection conn = DbHelper.GetConnection()) { conn.Open(); string sql = "DELETE FROM Products WHERE ProductID = @ProductID"; MySqlCommand cmd = new MySqlCommand(sql, conn); cmd.Parameters.AddWithValue("@ProductID", productId); return cmd.ExecuteNonQuery(); } } } } ``` 类似地,创建`InboundDAL`, `OutboundDAL`, `UserDAL`等。 ### 4. 业务逻辑层(BLL) 创建类库项目`WarehouseManagement.BLL`,并添加对`WarehouseManagement.DAL`的引用。 #### 4.1 产品业务逻辑类(ProductBLL.cs) 处理业务逻辑,例如验证、事务等。 ```csharp using WarehouseManagement.DAL; using WarehouseManagement.DAL.Models; namespace WarehouseManagement.BLL { public class ProductBLL { private readonly ProductDAL productDAL; public ProductBLL() { productDAL = new ProductDAL(); } public List<Product> GetAllProducts() { return productDAL.GetAllProducts(); } public bool AddProduct(Product product, out string errorMessage) { // 验证产品信息 if (string.IsNullOrEmpty(product.Name)) { errorMessage = "产品名称不能为空"; return false; } if (product.UnitPrice <= 0) { errorMessage = "产品单价必须大于0"; return false; } // 其他验证... try { int result = productDAL.AddProduct(product); errorMessage = ""; return result > 0; } catch (Exception ex) { errorMessage = ex.Message; return false; } } // 更新和删除类似 } } ``` #### 4.2 库存操作业务逻辑(带事务) 以入库操作为例,需要同时更新库存和添加入库记录,使用事务。 在`InboundBLL.cs`中: ```csharp using WarehouseManagement.DAL; using WarehouseManagement.DAL.Models; using MySql.Data.MySqlClient; namespace WarehouseManagement.BLL { public class InboundBLL { private readonly InboundDAL inboundDAL; private readonly ProductDAL productDAL; public InboundBLL() { inboundDAL = new InboundDAL(); productDAL = new ProductDAL(); } public bool AddInboundOrder(int productId, int quantity, out string errorMessage) { // 验证数量 if (quantity <= 0) { errorMessage = "入库数量必须大于0"; return false; } using (MySqlConnection conn = DbHelper.GetConnection()) { conn.Open(); MySqlTransaction transaction = conn.BeginTransaction(); try { // 添加入库记录 int result1 = inboundDAL.AddInboundOrder(conn, transaction, productId, quantity); // 更新产品库存 int result2 = productDAL.UpdateProductStock(conn, transaction, productId, quantity); if (result1 > 0 && result2 > 0) { transaction.Commit(); errorMessage = ""; return true; } else { transaction.Rollback(); errorMessage = "入库操作失败"; return false; } } catch (Exception ex) { transaction.Rollback(); errorMessage = ex.Message; return false; } } } } } ``` 注意:在DAL中需要为`InboundDAL`和`ProductDAL`添加使用现有连接和事务的方法。 例如,在`InboundDAL`中添加: ```csharp public int AddInboundOrder(MySqlConnection conn, MySqlTransaction transaction, int productId, int quantity) { string sql = "INSERT INTO InboundOrders (ProductID, Quantity) VALUES (@ProductID, @Quantity)"; MySqlCommand cmd = new MySqlCommand(sql, conn); cmd.Transaction = transaction; cmd.Parameters.AddWithValue("@ProductID", productId); cmd.Parameters.AddWithValue("@Quantity", quantity); return cmd.ExecuteNonQuery(); } ``` 在`ProductDAL`中添加: ```csharp public int UpdateProductStock(MySqlConnection conn, MySqlTransaction transaction, int productId, int quantityToAdd) { string sql = "UPDATE Products SET StockQuantity = StockQuantity + @Quantity WHERE ProductID = @ProductID"; MySqlCommand cmd = new MySqlCommand(sql, conn); cmd.Transaction = transaction; cmd.Parameters.AddWithValue("@Quantity", quantityToAdd); cmd.Parameters.AddWithValue("@ProductID", productId); return cmd.ExecuteNonQuery(); } ``` ### 5. 用户界面层(WinForms) 创建Windows Forms项目`WarehouseManagement.WinForms`,添加对`WarehouseManagement.BLL`的引用。 #### 5.1 登录窗体(LoginForm.cs) 实现用户登录功能。 #### 5.2 主窗体(MainForm.cs) 包含菜单栏,用于打开各个功能模块。 #### 5.3 产品管理窗体(ProductManagementForm.cs) 展示产品列,支持增删改查操作。 ```csharp public partial class ProductManagementForm : Form { private ProductBLL productBLL; public ProductManagementForm() { InitializeComponent(); productBLL = new ProductBLL(); } private void ProductManagementForm_Load(object sender, EventArgs e) { LoadProducts(); } private void LoadProducts() { dataGridViewProducts.DataSource = productBLL.GetAllProducts(); } private void btnAdd_Click(object sender, EventArgs e) { Product product = new Product(); // 从文本框获取数据赋值给product string errorMessage; if (productBLL.AddProduct(product, out errorMessage)) { MessageBox.Show("添加成功"); LoadProducts(); } else { MessageBox.Show("添加失败:" + errorMessage); } } // 其他事件处理 } ``` #### 5.4 入库操作窗体(InboundForm.cs) 选择产品,填写数量,执行入库操作。 ### 6. 部署发布 1. **发布WinForms应用**: - 在Visual Studio中,右键点击WinForms项目 -> 发布 - 选择发布目标(文件夹、FTP等) - 配置发布设置(.NET版本,是否独立部署等) 2. **数据库部署**: - 将数据库脚本(SQL文件)在MySQL服务器上执行 - 配置生产环境的连接字符串(在appsettings.json中,但发布后可能需要手动修改,或者使用配置文件覆盖) 3. **安装包制作**: - 可以使用Inno Setup等工具制作安装程序,包含.NET运行环境和MySQL数据库初始化脚本(如果必要)。 ### 7. 安全注意事项 - 数据库连接字符串不要硬编码,使用配置文件,并且生产环境要保护配置文件。 - 密码存储:使用哈希加盐存储(例如使用`BCrypt.Net`库)。 - 权限控制:根据用户角色限制功能访问。 由于篇幅限制,以上只列出了关键代码和步骤。实际开发中需要完善异常处理、日志记录等。 §§相关问题§§ 1. 如何设计仓库管理系统的数据库结构? 2. 使用Dapper和Entity Framework Core有什么区别? 3. 如何在C#中处理MySQL数据库事务? 4. WinForms中如何实现数据验证和错误处理? 5. 如何将仓库管理系统部署到生产环境? 注意:在实现过程中,可以根据实际需求调整架构和功能。 </think> # C#MySQL开发仓库管理系统全流程指南 ## 一、系统架构设计 仓库管理系统采用经典三层架构设计,确保代码的可维护性和可扩展性: ```mermaid graph TD A[示层 UI] -->|调用| B[业务逻辑层 BLL] B -->|调用| C[数据访问层 DAL] C -->|操作| D[MySQL数据库] D -->|返回数据| C C -->|返回| B B -->|返回| A ``` ### 三层架构职责 1. **数据访问层(DAL)**:封装数据库操作 2. **业务逻辑层(BLL)**:处理业务规则和事务 3. **示层(UI)**:提供用户界面和交互 ## 二、数据库设计 ### 核心结构设计 ```sql -- 产品 CREATE TABLE Products ( ProductID INT AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Category VARCHAR(50), UnitPrice DECIMAL(10,2) NOT NULL, StockQuantity INT NOT NULL DEFAULT 0, Description TEXT, CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 入库记录 CREATE TABLE InboundOrders ( InboundID INT AUTO_INCREMENT PRIMARY KEY, ProductID INT NOT NULL, Quantity INT NOT NULL, Operator VARCHAR(50), InboundDate DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ); -- 出库记录 CREATE TABLE OutboundOrders ( OutboundID INT AUTO_INCREMENT PRIMARY KEY, ProductID INT NOT NULL, Quantity INT NOT NULL, Operator VARCHAR(50), OutboundDate DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ); -- 用户 CREATE TABLE Users ( UserID INT AUTO_INCREMENT PRIMARY KEY, Username VARCHAR(50) NOT NULL UNIQUE, Password VARCHAR(100) NOT NULL, Role VARCHAR(20) NOT NULL DEFAULT 'Operator', LastLogin DATETIME ); ``` ## 三、数据访问层(DAL)实现 ### 数据库帮助类 ```csharp public static class DbHelper { private static readonly string _connectionString; static DbHelper() { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); _connectionString = config.GetConnectionString("WarehouseDB"); } public static MySqlConnection GetConnection() => new MySqlConnection(_connectionString); } ``` ### 产品数据访问类 ```csharp public class ProductDAL { public List<Product> GetAllProducts() { using (var conn = DbHelper.GetConnection()) { conn.Open(); string sql = "SELECT * FROM Products"; return conn.Query<Product>(sql).ToList(); } } public int AddProduct(Product product) { using (var conn = DbHelper.GetConnection()) { conn.Open(); string sql = @"INSERT INTO Products (Name, Category, UnitPrice, StockQuantity, Description) VALUES (@Name, @Category, @UnitPrice, @StockQuantity, @Description)"; return conn.Execute(sql, product); } } public int UpdateStock(int productId, int quantityChange) { using (var conn = DbHelper.GetConnection()) { conn.Open(); string sql = "UPDATE Products SET StockQuantity = StockQuantity + @Change WHERE ProductID = @ProductID"; return conn.Execute(sql, new { ProductID = productId, Change = quantityChange }); } } } ``` ## 四、业务逻辑层(BLL)实现 ### 库存管理服务 ```csharp public class InventoryService { private readonly ProductDAL _productDal = new ProductDAL(); public List<Product> GetAllProducts() => _productDal.GetAllProducts(); public bool AddProduct(Product product, out string errorMsg) { if (product.UnitPrice <= 0) { errorMsg = "单价必须大于0"; return false; } try { _productDal.AddProduct(product); errorMsg = ""; return true; } catch (Exception ex) { errorMsg = $"添加产品失败: {ex.Message}"; return false; } } public bool ProcessInbound(int productId, int quantity, string operatorName) { using (var conn = DbHelper.GetConnection()) { conn.Open(); using (var transaction = conn.BeginTransaction()) { try { // 添加入库记录 string sql = @"INSERT INTO InboundOrders (ProductID, Quantity, Operator) VALUES (@ProductID, @Quantity, @Operator)"; conn.Execute(sql, new { ProductID = productId, Quantity = quantity, Operator = operatorName }, transaction); // 更新库存 _productDal.UpdateStock(productId, quantity, conn, transaction); transaction.Commit(); return true; } catch { transaction.Rollback(); throw; } } } } } ``` ## 五、示层(UI)实现 ### 产品管理窗体 ```csharp public partial class ProductManagementForm : Form { private readonly InventoryService _inventoryService = new InventoryService(); public ProductManagementForm() { InitializeComponent(); LoadProducts(); } private void LoadProducts() { dataGridViewProducts.DataSource = _inventoryService.GetAllProducts(); dataGridViewProducts.AutoResizeColumns(); } private void btnAddProduct_Click(object sender, EventArgs e) { var product = new Product { Name = txtName.Text, Category = txtCategory.Text, UnitPrice = decimal.Parse(txtPrice.Text), StockQuantity = (int)numStock.Value, Description = txtDescription.Text }; if (_inventoryService.AddProduct(product, out string errorMsg)) { MessageBox.Show("产品添加成功"); LoadProducts(); } else { MessageBox.Show(errorMsg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } ``` ### 出入库操作界面 ```csharp public partial class InventoryOperationForm : Form { private readonly InventoryService _inventoryService = new InventoryService(); public InventoryOperationForm() { InitializeComponent(); LoadProducts(); } private void LoadProducts() { cmbProducts.DataSource = _inventoryService.GetAllProducts(); cmbProducts.DisplayMember = "Name"; cmbProducts.ValueMember = "ProductID"; } private void btnInbound_Click(object sender, EventArgs e) { int productId = (int)cmbProducts.SelectedValue; int quantity = (int)numQuantity.Value; if (_inventoryService.ProcessInbound(productId, quantity, CurrentUser.Username)) { MessageBox.Show("入库操作成功"); UpdateStockDisplay(); } else { MessageBox.Show("入库操作失败"); } } private void UpdateStockDisplay() { var product = (Product)cmbProducts.SelectedItem; lblCurrentStock.Text = $"当前库存: {product.StockQuantity}"; } } ``` ## 六、部署发布 ### 发布流程 1. **生成发布包**: ```bash dotnet publish -c Release -r win-x64 --self-contained true ``` 2. **数据库部署**: - 在MySQL服务器执行数据库脚本 - 配置生产环境连接字符串 3. **安装包制作**: - 使用Inno Setup创建安装程序 - 包含.NET运行时(如未使用自包含部署) ### 配置文件示例 (appsettings.json) ```json { "ConnectionStrings": { "WarehouseDB": "server=proddb.example.com;database=WarehouseDB;user=appuser;password=P@ssw0rd!;port=3306" }, "Logging": { "LogLevel": { "Default": "Information", "System": "Warning", "Microsoft": "Warning" } } } ``` ## 七、安全实践 ### 密码安全处理 ```csharp public static class SecurityHelper { public static string HashPassword(string password) { // 使用PBKDF2算法进行密码哈希 using var deriveBytes = new Rfc2898DeriveBytes( password, saltSize: 16, iterations: 10000); byte[] salt = deriveBytes.Salt; byte[] hash = deriveBytes.GetBytes(20); // 组合salt和hash byte[] hashBytes = new byte[36]; Array.Copy(salt, 0, hashBytes, 0, 16); Array.Copy(hash, 0, hashBytes, 16, 20); return Convert.ToBase64String(hashBytes); } public static bool VerifyPassword(string password, string hashedPassword) { byte[] hashBytes = Convert.FromBase64String(hashedPassword); byte[] salt = new byte[16]; Array.Copy(hashBytes, 0, salt, 0, 16); using var deriveBytes = new Rfc2898DeriveBytes(password, salt, 10000); byte[] newHash = deriveBytes.GetBytes(20); for (int i = 0; i < 20; i++) { if (hashBytes[i + 16] != newHash[i]) return false; } return true; } } ``` ## 结论 通过以上步骤,您已实现了一个完整的仓库管理系统,具备以下特点: - 采用三层架构确保系统可维护性 - 使用MySQL作为数据存储 - 实现事务处理保证数据一致性 - 包含完善的异常处理机制 - 提供安全的用户认证 - 支持高效部署方案 此系统可作为企业级应用的坚实基础,后续可根据需求扩展报生成、多仓库管理、供应商管理等功能[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值