C#.net實驗——數據庫應用管理系統

一.實驗要求

      掌握並運用ADO.NET技術,實現一個C/S版本的信息管理系統。

(1)設計一個學生成績管理信息系統,能對學生的成績記錄進行方便的輸入、查詢、修改等操作,以及綜合統計查詢等。

(2)對學生成績的綜合查詢,如查詢個人的單科或所有成績/不及格成績,查詢某門課程的所有程序等。

(3)參考示例文件DbDemo。

(4)至少實現對一個數據表的完整操作(CRUD,增刪查改)、綜合(複合條件)查詢。

(5)鼓勵使用分層方式完成實驗。

(6)正確理解和熟練運用ADO.NET 數據訪問模型,理解並練習運用數據庫相關理論:事務、關係/外鍵約束、存儲函數等。

二. 設計思路

       本次實驗是要做一個基於數據庫的應用軟件,採用了表示層、業務邏輯層和數據訪問層的三層結構。由於之前做數據庫課程設計已經採用過C#和Linq完成,所以我使用Linq來操作數據,相對來說會比較熟悉,所以這次的實驗仍然採用Linq來完成——使用Linq讀取和操作數據,再綁定到控件上。

1.數據訪問層(代碼在Model文件夾內)

       數據訪問層主要分爲兩個部分,一個部分是DBContext的建立,另外一部分是把每一個數據庫表建立爲一個個獨立的對象,並聲明裏面的屬性。

//建立DBContext
public System.Data.Linq.Table<Classes> Classes;//聲明班級表對象
public System.Data.Linq.Table<Courses> Courses; //聲明課程表對象
public System.Data.Linq.Table<Roles> Roles; //聲明角色表對象
public System.Data.Linq.Table<Sorces> Sorces; //聲明成績表對象
public System.Data.Linq.Table<Student> Student;	//聲明學生表對象
public System.Data.Linq.Table<Users> Users; //聲明用戶表對象
public SchoolMgrDataSetDataContext():base(connectionString){} //數據庫上下文
//聲明對象表中的屬性以及數據類型,get、set操作,以班級表(Classes)爲例
[Key]//聲明ClassID爲主鍵
private int ClassID { get; set; };

[StringLength(4,ErrorMessage="請正確輸入4爲年份"),Required ]
private string Year { get; set; };

[StringLength(50,ErrorMessage="請正確專業"),Required ]
private string Major{ get; set; };

[Required(ErrorMessage="請輸入班號!")]
private int ClassNumber{ get; set; };

private EntitySet<Student> _Student;

2.邏輯業務層(代碼在Logic文件夾內)

       該層主要是用於接收來時表示層的數據處理請求,包括對數據的增刪查改,以及數據庫中表與表之間的各種連接。

//增:以在成績表中增加一條成績記錄爲例
try
{
    SchoolMgr.Model.SchoolMgrDataSetDataContext myDB = 
new Model.SchoolMgrDataSetDataContext();
//建立數據庫上下文
    var mySorce = 
myDB.Sorces.Where(p => p.CourseID == CourseID && p.StudentID == StudentID);
//檢查準備插入的成績記錄是否已經在表中,以防重複插入

    if (mySorce.Count() ==0)//如果成績表(Sorce)中沒有該數據則插入
    {
        var myNewSorce = new Model.Sorces();//新建一個成績表元組對象
        myNewSorce.CourseID = CourseID;//課程ID
        myNewSorce.StudentID = StudentID;//學號
        myNewSorce.Sorce = SorceNumber;//成績
        myDB.Sorces.InsertOnSubmit(myNewSorce);//在成績表插入該記錄
    }
    ……
    myDB.SubmitChanges();//提交插入,由於在數據庫中已經採用了Check的約束,
//如果成績不在0~100之間的範圍內,將會出現異常。
    return true;//如果插入成功,就返回true,表示插入成功。
}
catch 
{ 
return false;//插入失敗,返回false,表示插入失敗。
}

//刪:以刪除一條成績記錄爲例。
SchoolMgr.Model.SchoolMgrDataSetDataContext myDB = 
new Model.SchoolMgrDataSetDataContext();
var mySorceLog = myDB.Sorces.First(p => p.SorceID == SorceID);
												//查找出需要被刪除的元組
try
{
    myDB.Sorces.DeleteOnSubmit(mySorceLog);//刪除該元組
    myDB.SubmitChanges();//提交
    return true;//如果刪除成功,則不會有異常出現,返回刪除成功
}
catch
{ 
return false; //如果刪除失敗,則會有出現異常,返回刪除失敗
}
//刪:以刪除成績表中某學號的所有成績記錄爲例,同時刪除多條記錄
SchoolMgr.Model.SchoolMgrDataSetDataContext myDB = 
new Model.SchoolMgrDataSetDataContext();
IEnumerable<SchoolMgr.Model.Sorces> deleteSorceLog = 
myDB.Sorces.Where(p => p.StudentID.Contains(StudentID));
								//選擇出包含(Contain)StudentID的成績記錄
try
{
    myDB.Sorces.DeleteAllOnSubmit(deleteSorceLog);//刪除枚舉隊列中的所有元組
    myDB.SubmitChanges();//提交到數據庫
    return true;
}
catch
{
    return false;
}

//查:以顯示一張成績表爲例,根據學號,找出某名學生的所有課程的成績。
SchoolMgr.Model.SchoolMgrDataSetDataContext myDB =
    										new Model.SchoolMgrDataSetDataContext();

//以下是自然連接的Linq語句
IQueryable<SchoolMgr.Model.SorceTable> sorceTable =
    from myClass in myDB.Classes
    join myStudent in myDB.Student.Where(p => p.StudentID == StudentID)
        on myClass.ClassID equals myStudent.ClassID
    into myStudentClasses
    from myStudentClass in myStudentClasses
						//獲得該學生的學生信息:班級、姓名和學號
    join mySorce in myDB.Sorces
        on myStudentClass.StudentID equals mySorce.StudentID
    into mySoceStudentClasses
						//獲得該學生的成績信息:成績
    from mySorceStudentClass in mySoceStudentClasses
    join myCourse in myDB.Courses
        on mySorceStudentClass.CourseID equals myCourse.CourseID
    into myCourseSorceStudentClasses
						//獲得該學生的課程信息:課程名稱
    from myCourseSorceStudentClass in myCourseSorceStudentClasses
    join myTeacher in myDB.Users
        on myCourseSorceStudentClass.UserName equals myTeacher.UserName
    into myTeacherCourseSorceStudentClasses
						//獲得該學生的學生信息:班級、姓名和學號
    from myTeacherCourseSorceStudentClass in myTeacherCourseSorceStudentClasses
    select new SchoolMgr.Model.SorceTable
    {
        ClassName = myCourseSorceStudentClass.CourseName,
        StudentID = StudentID,
        StudentName = myStudentClass.StudentName,
        CourseName = myCourseSorceStudentClass.CourseName,
        TeacherName = myTeacherCourseSorceStudentClass.UserNickName,
        SorceNumber = mySorceStudentClass.Sorce
    };
        
return sorceTable;//返回成績單表

//改:以下以修改成績單中的成績爲例。
SchoolMgr.Model.SchoolMgrDataSetDataContext myDB =
    										new Model.SchoolMgrDataSetDataContext();
SchoolMgr.Model.Sorces mySorceLog = 
myDB.Sorces.FirstOrDefault(p => p.SorceID == SorceID);
								//在成績單表中找到該記錄
if (mySorceLog != null)//如果存在該記錄,則修改成績
{
    try
    {
        mySorceLog.Sorce = SorceNumber;//修改成績
        myDB.SubmitChanges();//提交到數據庫
        return true;//修改成功,返回true
    }
    catch { }
}

return false;//修改失敗或不存在該記錄返回false

3.表示層(界面、功能設計部分)

       在這個部分,主要是對應用具體功能的實現部分,包括登錄驗證、各種控件的數據綁定、成績錄入、條件查詢、成績分析等功能的代碼實現部分。

//登錄驗證部分代碼
if (TextboxUserName.Text.Trim().Length <= 0)//驗證用戶名不爲空
{
    TextboxUserName.Focus();
    MessageBox.Show("請輸入用戶名!");
}
else if (TextboxPassword.Text.Trim().Length <= 0)//驗證密碼不爲空
{
    TextboxPassword.Focus();
    MessageBox.Show("請輸入密碼!");
}
else
{
    SchoolMgr.Logic.Users myUsers = new Logic.Users();
    if (myUsers.IsUser(TextboxUserName.Text, TextboxPassword.Text))
    {
        ……//登錄成功
    }
    else
    {
        MessageBox.Show("用戶名、密碼輸入錯誤或該用戶不存在!");
		//登錄失敗提示
    }
}


//數據綁定:以課程選擇下拉框(ComboBoxList)的數據綁定爲例。
SchoolMgr.Logic.Courses myCourse = new Logic.Courses();//新建邏輯層的課程對象
ComboBoxCourse.DataSource = myCourse.GetCoursesList();//獲取課程列表
ComboBoxCourse.DisplayMember = "CourseName";//下拉框顯示的內容的屬性
ComboBoxCourse.ValueMember = "CourseID";//下拉框選項值的值屬性
ComboBoxCourse.SelectedIndex = -1;//當前選中的項的索引設置爲-1(未選中)


//數據錄入部分,以插入新的成績記錄或修改成績記錄爲例。
if (e.RowIndex >= 0)//如果被修改的行的索引大於等於0
{
    DataGridViewRow myRow = DataGridViewSorce.Rows[e.RowIndex];//獲得被修改的行
    SchoolMgr.Logic.Sorce mySorce = new Logic.Sorce();//新建邏輯層的成績對象
    SchoolMgr.Logic.Courses myCourse = new Logic.Courses();//新建邏輯層的課程對象
    int CourseID = myCourse.GetCourseIDByTeacherNameAndCourseName(
        (string)myRow.Cells[4].Value, (string)myRow.Cells[3].Value
        );//獲得被修改行的課程ID
    bool isOK = mySorce.InsertOrUpdateSorceLog(
        CourseID,
        (string)myRow.Cells[1].Value,
        (double)myRow.Cells[5].Value);//在數據庫中插入該記錄或更新該記錄的成績

……//提示語句,如果修改失敗則彈出框進行提示,提示用戶重新輸入合法的成績。
}


//成績查詢,以學生查詢自身學號下所用課程的成績爲例。
string studentID = TextboxStudentID.Text.Trim().toString();//從學號輸入框中獲得學生學號

SchoolMgr.Logic.Sorce mySorce = new Logic.Sorce();
var mySorceTable = mySorce.GetSorceTable(studentID);//獲取學生的所有課程的成績
if (mySorceTable != null)//返回的成績單不爲空
{
    DataGridViewSorce.DataSource = mySorceTable;//將成績單顯示在主界面的表格中
}
else
{
MessageBox.Show("輸入的學號有誤,請重新輸入!");
//如果查詢的成績單爲空,則提示用戶輸入正確的學號。
}

//綜合統計查詢,下面以成績分析爲例。
double[] SorceNumber = new double[DataGridViewSorce.Rows.Count];
int i=0;
foreach (DataGridViewRow x in DataGridViewSorce.Rows)
{
    SorceNumber[i] = (double)x.Cells[5].Value;//獲得成績表中的成績
    i++;
}
SchoolMgr.Logic.Sorce mySorce = new Logic.Sorce();
int[] Analysisesult = mySorce.GetSorceAnalysis(SorceNumber);
//成績分析返回的結果,分別是不及格、及格、良好、優秀的4級的人數
i=DataGridViewSorce.Rows.Count;
Below60Label.Text = 
string.Format("不及格(<60):{0}人,{1}%", 
Analysisesult[0], Math.Round(Analysisesult[0] / i * 100.0, 2));
//以文字形式顯示成績分析結果
ChartSorceAnalysis.DataSource = Analysisesult;
							//以圖片形式顯示結果

三. 程序運行效果圖

1.登錄功能

       啓動本應用,首先我們需要輸入用戶名和密碼,每個用戶的用戶名和密碼都在數據庫中記錄,其中用戶的密碼會以加密的方式在數據庫中記錄,如圖1所示。

圖1 以加密的形式記錄用戶密碼


圖2 輸入用戶名和密碼

       正確輸入用戶名和密碼(圖2)後,會提示登錄成功,並顯示主界面。

圖3 登錄成功


圖4 主界面


2. 增:以插入成績記錄到成績表中爲例

       打開菜單欄的“開始”,點擊“新建成績單”,就會彈出新建成績單窗口,選擇課程和班級,選中需要記錄成的學生名單,如圖5所示。點擊“進入成績錄入”,成績單表格將會在主界面中顯示,如圖6所示。


圖4 “開始”菜單


圖5 新建成績單窗口

圖6 新建的成績單
       點擊成績表中的“成績”屬性學生的單元格,可以直接錄入成績,鍵入回車,應用會提示成績錄入是否成功。如果錄入成功,應用會在主界面的底下的狀態欄上顯示插入或修改成功記錄,如圖7所示。

圖7 插入或修改成績成功的提示


圖8 插入或修改的成績格式有誤的提示
       如果輸入的成績不合法,應用則會提示修改錯誤,要求用戶輸入正確的成績,如圖8所示。

3.查:以“打開成績單”爲例

       打開菜單欄的“開始”,點擊“打開成績單”,就會彈出打開成績單窗口,選擇課程或班級中的一個或兩個條件,如圖9所示。點擊“打開成績單”,成績單表格將會在主界面中顯示。


圖8 打開成績單窗口

4. 條件查詢:以“按班級查詢”或“按課程名稱”查詢學生成績爲例

       打開菜單欄的“查詢”,點擊“按課程查詢成績”,如圖10所示,就會彈出課程選擇窗口,選擇課程,如圖11所示。點擊“打開成績單”,將會在主界面中顯示選中課程的所有學生的成績單。


圖10 打開成績單窗口


圖11 打開成績單窗口

       類似地,“按班級查詢成績”實現的功能與“按課程查詢成績”類似。個性化查詢則提供了6個不同的條件的單條件查詢,如圖12所示。點擊“查詢成績”,將會在主界面中顯示對應條件下的成績單。


圖12 個性化查詢成績

       打開菜單欄的“分析”,點擊“成績分析”,應用將會在對當前打開的成績單進行成績分析,包括文字、餅圖和柱狀圖的成績分析,如圖14~16所示。


圖13 個性化查詢成績

圖14 文字成績分析


圖15 柱狀圖成績分析


圖16 餅圖成績分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章