WinForm连接多个数据库并对数据库进行多种Sql查询操作

项目要求

本项目旨在熟悉在C#的环境下对数据库进行连接并进行相关的sql操作。

基本目标:

  • 实现对不同数据库的连接
  • 设计数据表以支持不同的Sql操作

实现思路

  • 由于要连接不同的数据库,则可以直接定义一个连接数据库的工具类,用于处理数据库的连接
  • 考虑到Navicat不能管理Access数据库,因此,设计一个界面,允许用户输入建表的sql语句,以此实现便捷化建表
  • 此项目的目的是熟悉数据库的连接以及sql的使用,因此,在本项目中,未使用实体类来对应查询结果,而是将查询到的结果直接转换为DataTable,并据此来对 DataGridView中的数据进行绑定。

实现效果

程序主界面
建表界面

数据设计

为了对Sql语句进行充分的练习,建表的背景是学生的选课信息以及每门课程的信息。

包含四个表:

  • Students 表:存储学生的信息。
  • Courses 表:存储课程的信息。
  • Enrollments 表:存储学生选课的信息。
  • Grades 表:存储学生每门课的成绩。

下面是详细的建表过程:

CREATE TABLE Enrollments (
    EnrollmentID TEXT(36) PRIMARY KEY,
    StudentID TEXT(36),
    CourseID TEXT(36),
    EnrollmentDate DATE,
    CONSTRAINT FK_Student FOREIGN KEY (StudentID) REFERENCES Students(StudentID),
    CONSTRAINT FK_Course FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)
);

CREATE TABLE Students (
    StudentID TEXT(36) PRIMARY KEY,
    StudentName TEXT(50),
    Age INT,
    Gender TEXT(10),
    Major TEXT(50)
);

CREATE TABLE Courses (
    CourseID TEXT(36) PRIMARY KEY,
    CourseName TEXT(100),
    Credits INT
);

CREATE TABLE Grades (
    GradeID TEXT(36) PRIMARY KEY,
    StudentID TEXT(36),
    CourseID TEXT(36),
    Grade DECIMAL(3, 2),
    CONSTRAINT FK_GradeStudent FOREIGN KEY (StudentID) REFERENCES Students(StudentID),
    CONSTRAINT FK_GradeCourse FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)
);

SQL语句练习

查询所有学生及其所选课程和成绩的信息:

SELECT s.StudentName, c.CourseName, e.EnrollmentDate, g.Grade
FROM (Enrollments e
JOIN Students s ON e.StudentID = s.StudentID)
JOIN Courses c ON e.CourseID = c.CourseID
LEFT JOIN Grades g ON e.StudentID = g.StudentID AND e.CourseID = g.CourseID;

查询每门课程的选课人数:

SELECT c.CourseName, COUNT(e.StudentID) AS NumberOfStudents
FROM Enrollments e
JOIN Courses c ON e.CourseID = c.CourseID
GROUP BY c.CourseName;

查询每位学生的选课总学分:

SELECT s.StudentName, SUM(c.Credits) AS TotalCredits
FROM (Enrollments e
JOIN Students s ON e.StudentID = s.StudentID)
JOIN Courses c ON e.CourseID = c.CourseID
GROUP BY s.StudentName;

查询每个专业的学生平均年龄:

SELECT s.Major, AVG(s.Age) AS AverageAge
FROM Students s
GROUP BY s.Major;

关键点实现

数据库帮助类的实现

通过 传入的数据库类型来进行不同的数据库连接操作,数据库连接字符串的配置放在App.config 里面,需要注意的是,App.config 的根目录是bin/debug文件。

数据库连接字符串

  <connectionStrings>
    <add name="SqlServerConnectionString" connectionString="Server = localhost; Database = Student; User Id = sa; Password = admin123;" providerName="System.Data.SqlClient" />
    <add name="SqliteConnectionString" connectionString="Data Source=studentGrade.db;Version=3;" providerName="System.Data.SqlClient" />
    <add name="AccessConnectionString" connectionString= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=studentGrade.accdb;Persist Security Info=False;" providerName="System.Data.SqlClient" />
  </connectionStrings>

通过ConfigurationManager类去获取值。

        // 构造函数,接受数据库类型和连接字符串
        public DbHelper(DatabaseType dbType)
        {
            switch (dbType)
            {
                case DatabaseType.SqlServer:
                    connectionString = ConfigurationManager.ConnectionStrings["SqlServerConnectionString"].ConnectionString;
                    connection = new SqlConnection(connectionString);
                    break;
                case DatabaseType.SqLite:

                    connectionString = ConfigurationManager.ConnectionStrings["SqliteConnectionString"].ConnectionString;
                    connection = new SQLiteConnection(connectionString);
                    break;
                case DatabaseType.Access:
                    connectionString = ConfigurationManager.ConnectionStrings["AccessConnectionString"].ConnectionString;
                    connection = new OleDbConnection(connectionString);
                    break;
                default:
                    throw new NotSupportedException("不支持的数据库类型");
            }
        }

Dapper 数据转DataTable的实现

 public static class DataTableHelper
 {
     public static DataTable ToDataTable(this IEnumerable<dynamic> items)
     {
         var dataTable = new DataTable();
         if (items == null || !items.Any())
         {
             return dataTable;
         }

         var firstItem = (IDictionary<string, object>)items.First();

         foreach (var key in firstItem.Keys)
         {
             dataTable.Columns.Add(key);
         }

         foreach (var item in items)
         {
             var dataRow = dataTable.NewRow();
             var dictionary = (IDictionary<string, object>)item;

             foreach (var key in dictionary.Keys)
             {
                 dataRow[key] = dictionary[key] ?? DBNull.Value;
             }

             dataTable.Rows.Add(dataRow);
         }

         return dataTable;
     }
 }

遇到的问题

  1. Sqlite 在当前目录下创建了数据库,但是看不到,需要执行一个./database 才会显示
  2. 注意连接字符串的数据库存放的地址
  3. Access 的SQL语法与常用的有些许不同,需要单独考考虑
  4. Sqlite 的一个 xx.dll文件需要手动放到Debug文件下,还需要注意是32位的还是64位的

总结与展望

  1. 数据库连接类的是必不可少的,能简化很多操作。
  2. 目前程序很多地方都不完善,没有对异常进行处理,没有进行事务的操作等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值