C#与Sql server 2008 R2图书信息管理系统源码(带注释,VS2015版本,.n...
·
C#与Sql server 2008 R2图书信息管理系统,源码带注释,VS2015版本,.net4.5框架

最近在整理硬盘翻出个古董项目——基于C#和SQL Server 2008 R2的图书管理系统。虽然技术栈有点年头,但架构设计现在看依然有参考价值。随手打开尘封的VS2015解决方案,带各位看看当年码农的生存现状(笑)。

数据库连接模块有个挺有意思的封装,直接看这段带味道的代码:
public class DBHelper
{
// 记得当年被这个连接字符串折磨了三天
private static string connStr = @"Data Source=.\SQLEXPRESS;
Initial Catalog=BookDB;
Integrated Security=True;
Pooling=false";
public static SqlConnection GetConnection()
{
var conn = new SqlConnection(connStr);
// 这里埋过雷:曾经漏了Open()直接返回
conn.Open();
return conn;
}
}
当年没好好用using语句,现在看这个连接池设置成false简直作死。不过亮点在异常处理——全局只在一处捕获,典型的新手操作(别学):
try
{
using(var conn = DBHelper.GetConnection())
{
var cmd = new SqlCommand("SELECT * FROM Books WHERE Price > @price", conn);
cmd.Parameters.AddWithValue("@price", 50); // 比拼接字符串安全多了
// 这里有个坑:当年不知道SqlDataAdapter会自动开闭连接
var adapter = new SqlDataAdapter(cmd);
var table = new DataTable();
adapter.Fill(table);
return table;
}
}
catch(SqlException ex)
{
// 曾经直接throw ex把堆栈信息丢了,被师傅骂惨
throw new Exception("数据库抽风了", ex);
}
数据访问层用了个半吊子的仓储模式,这查询方法现在看简直暴力:
public List<Book> SearchBooks(string keyword)
{
// 当年不知道LINQ to SQL的好,硬怼SQL
string sql = "SELECT * FROM Books WHERE Title LIKE '%'+@key+'%'
OR Author LIKE '%'+@key+'%'";
// 参数化查询防注入是最后的倔强
var param = new SqlParameter("@key", SqlDbType.NVarChar) { Value = keyword };
// 手动映射字段的过程极其枯燥
using(var reader = ExecuteReader(sql, param))
{
var list = new List<Book>();
while(reader.Read())
{
var book = new Book();
book.Id = Convert.ToInt32(reader["Id"]);
// 这里曾经因为字段名大小写不一致崩过
book.ISBN = reader["ISBN"].ToString().Trim();
// ...其他字段赋值
list.Add(book);
}
return list;
}
}
界面层用了WinForm,DataGridView直接绑定DataTable这种上古操作:
private void btnSearch_Click(object sender, EventArgs e)
{
// UI线程直接操作数据库,现在看要报警
var keyword = txtKeyword.Text.Trim();
var books = _bookService.SearchBooks(keyword);
// 当年不知道BindingSource,直接暴力刷新
dataGridView1.DataSource = null;
dataGridView1.DataSource = books;
// 这个列头处理方式太硬核
dataGridView1.Columns["Id"].HeaderText = "编号";
dataGridView1.Columns["ISBN"].HeaderText = "国际书号";
// ...其他列配置
}
最骚的是导出Excel功能,用到了古老的Office Interop:
var excelApp = new Microsoft.Office.Interop.Excel.Application();
// 没处理COM对象释放,运行几次就内存泄漏
var workbook = excelApp.Workbooks.Add();
var worksheet = (Worksheet)workbook.Worksheets[1];
// 用单元格坐标硬编码,改需求得重写
worksheet.Cells[1, 1] = "图书清单";
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
// 曾经因为索引越界在这里崩溃过N次
worksheet.Cells[i+2, 1] = dataGridView1.Rows[i].Cells["ISBN"].Value;
// ...其他列赋值
}
// 没有try-catch,Excel进程关不干净
workbook.SaveAs("C:\\temp\\export.xlsx");
excelApp.Quit();
这个项目虽然现在看槽点满满,但完整实现了增删改查、搜索、导出等基础功能。源码里随处可见的//TODO注释,记录着当年熬夜调试的血泪史。建议新人可以当反面教材学习,重点注意:
- 数据库连接池的正确配置
- 使用参数化查询防SQL注入
- 资源释放的规范写法(特别是COM对象)
- 业务逻辑与UI层的分离
- 异常处理的完整性
源码里最值钱的是那些被注释掉的错误写法,堪称初级程序员成长实录。想要完整代码的,老规矩——三连后私信(手动狗头)。




更多推荐
所有评论(0)