C#连接SQL Server数据库完整指南,整合了ADO.NET原生连接与Entity Framework Core两种实现方式。
这篇文件详细介绍C#代码连接
数据库的通用操作
数据库链接功能 数据库的增删改查操作
1 配置全局数据库链接字符串 App.config
2 获取数据库链接字符串
先在App.config配置连接字符串
<connectionStrings>
//name 自定义名称 服务器名称Server=ip地址 端口号;数据库名称 账号-密码
<add name="c1" connectionString="Server=.,1433;DataBase=SMDB;Uid=sa;Pwd=123456"/>
</connectionStrings>
server=.
:指定服务器名称为 .(自己计算机)
,表示数据库服务器位于本地计算机上。.用于指代本地主机。
database=SMDB
:指定要连接的数据库名称为 SMDB
。这意味着连接成功后,将在 SMDB
数据库上执行数据库操作。
uid=sa
:指定用户身份验证使用的用户名为 sa
。sa
是 SQL Server 中的系统管理员账户。
pwd=123456
:指定用户身份验证使用的密码为 123456
。
//获取
public static readonly string connstring = ConfigurationManager.ConnectionStrings["c1"].ToString();
注:也可以在c#创建字符串来设置连接字符串在进行获取
* 执行sql命令几个方法
* 1 cmd.ExCuteNonQuery 添加数据(insert into) 修改数据update 删除数据delete
* 2 cmd.ExcuteScalar select count(*)
* 3 cmd.ExcuteReader 返回的是sqlDatareader 管道 需要使用while循环, select *
* 4 SqlDataAdapter da = new DataAdapter(cmd) ,select * 场景
展示案例
获取单一结果的方法 列如 记录个数等功能
//获取单一结果的方法 列如 记录个数等功能
public static object GrSigleResult(string sql)
{
//1创建数据库连接
SqlConnection=new SqlConnection(connstring);
//2创建sql命令
SqlCommand cmd=new SqlCommand(sql,conn)
//打开连接执行命令
try
{
conn.open();
return cmd.ExecuteScalar();
}
catch(Exception){throw;}
finally{conn.Close();}
}
方法调用:
// 获取总人数
public static int GetStudentCount()
{
string sql = "select count(*) from Students";
return Convert.ToInt32(SQLHelper.GrtSigleResult(sql));
}
执行增删改查操作
//执行增删改查操作
public static int Update(string sql)
{
SqlConnection conn=new SqlConnection(connstring);
SqlCommand cmd=new SqlCommand(sql,conn);
try
{
conn.open();
return cmd.ExecuteNonQuery();
}
catch(Exception){throw;}
finally{conn.Close();}
}
方法调用:
public static bool ClockInSuccess(Attendance ad)
{
string sql = "insert into Attendance(CarNo) Values('{0}')";
sql = string.Format(sql,ad.CardNo);
try
{
SQLHelper.Update(sql);
return true;
}
catch (Exception)
{
throw;
}
}
SqlDataReader 存储数据库数据 获取数据的所有记录 要用while循环去读
public static SqlDataReader GetReader(string sql)
{
SqlConnection conn = new SqlConnection(connstring);
SqlCommand cmd = new SqlCommand(sql,conn);
try
{
conn.Open();
return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}
catch (Exception)
{
throw;
}
}
方法调用:
1 返回的是对象类型
public static Student GetStudentByCardNo(string cardNo)
{
string sql = "select StudentId,StudentName,Gender,Birthday,StudentIdNo,PhoneNumber,ClassName,StudentAddress,CardNo,StuImage from Students ";
sql += "inner join StudentClass on Students.ClassId = StudentClass.ClassId ";
sql += "where CardNo = '{0}'";
sql = string.Format(sql, cardNo);
SqlDataReader r = SQLHelper.GetReader(sql);
Student student = null;
if (r.Read())
{
student = new Student()
{
StudentId = Convert.ToInt32(r["StudentId"]),
StudentName = r["StudentName"].ToString(),
Gender = r["Gender"].ToString(),
BirthDay = Convert.ToDateTime(r["Birthday"]),
StudentIdNo = r["StudentIdNo"].ToString(),
PhoneNumber = r["PhoneNumber"].ToString(),
ClassName = r["ClassName"].ToString(),
StudentAddress = r["StudentAddress"].ToString(),
CarNo = r["CardNo"].ToString(),
StuImage = r["StuImage"] == null ? "" : r["StuImage"].ToString(),
};
}
r.Close();
return student;
}
2返回list集合
public static List<Student> GetScoreList(string cname)
{
//全校成绩
string sql = "select Students.StudentId, StudentName,ClassName,Gender,CSharp,SqlserverDB from Students inner join ScoreList on Students.StudentId=ScoreList.StudentId inner join StudentClass on StudentClass.ClassId = Students.ClassId ";
if (cname != null && cname.Length != 0)
{
//按照班级查询
sql += "where ClassName = '" + cname + "'";
}
SqlDataReader r = SQLHelper.GetReader(sql);
List<Student> list = new List<Student>();
while (r.Read())
{
list.Add(new Student()
{
StudentId = Convert.ToInt32(r["StudentId"]),
StudentName = r["StudentName"].ToString(),
Gender = r["Gender"].ToString(),
ClassName = r["ClassName"].ToString(),
CSharp = Convert.ToInt32(r["CSharp"]),
SqlserverDB = Convert.ToInt32(r["SqlserverDB"]),
});
}
r.Close();
return list;
}
获取所有的记录 返回的是dataset数据类型 不要逐条给实体类字段进行赋值
public static DataSet GetDateSet(string sql)
{
SqlConnection conn = new SqlConnection(connstring);
SqlCommand cmd = new SqlCommand(sql,conn);
DataSet ds=new DataSet();
SqlDataAdapter da=new SqlDataAdapter(cmd)
try
{
conn.Open();
da.Fill(ds); // 把数据表数据填充在dataset集合中
return ds;
}
catch (Exception)
{
throw;
}
finally { conn.Close() ; }
}
方法调用:
/// <summary>
/// 获取所有成绩的方法
/// </summary>
/// <returns></returns>
public static DataSet GetAllScore()
{
string sql = "select Students.StudentId,StudentName,ClassName,Gender,PhoneNumber,CSharp,SqlserverDB from ScoreList inner join Students on Students.StudentId = ScoreList.StudentId inner join StudentClass on StudentClass.ClassId = Students.ClassId";
return SQLHelper.GetDateSet(sql);
}
Ui:
private DataSet ds = null; // 放置所有的成绩 数据集
this.ds = ScoreService.GetAllScore();
获取服务器时间
public static DateTime GetDateTime()
{
return Convert.ToDateTime(GrtSigleResult("select getdate()"));
}
方法调用:
DateTime t0 = Convert.ToDateTime(SQLHelper.GetDateTime().ToShortDateString());
public static bool UpdateDBFormExcelByShiWu(List<string> list)
{
SqlConnection conn = new SqlConnection(connstring);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
try
{
conn.Open();
// 开启事物
cmd.Transaction = conn.BeginTransaction();
// 把list里面指令添加事务中
foreach (string s in list)
{
cmd.CommandText = s;
cmd.ExecuteNonQuery();
}
cmd.Transaction.Commit();
return true;
}
catch (Exception ex)
{
MessageBox.Show("添加失败," + ex);
return false;
}
finally
{
conn.Close();
}
}
方法调用:
public static bool SaveDataToDB(List<Student> list)
{
// 定义sql语句
StringBuilder sql = new StringBuilder("insert into Students ");
sql.Append("(StudentName,Gender,BirthDay,StudentIdNo,CardNo,Age,PhoneNumber,StudentAddress,ClassId) ");
sql.Append("values ");
sql.Append("('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}');");
// 2 创建一个保存sql语句的集合
List<string> sqlList = new List<string>();
// 3 遍历传递过来的学生集合对象
int i = 1213;
foreach (Student student in list)
{
string s = string.Format(sql.ToString(), student.StudentName, student.Gender,
student.BirthDay.ToString("yyyy-MM-dd"), student.StudentIdNo, student.CarNo+i, student.Age,
student.PhoneNumber, student.StudentAddress, student.ClassId);
sqlList.Add(s);
i++;
}
return SQLHelper.UpdateDBFormExcelByShiWu(sqlList);
}
SQL注入
当我们要在登录账号密码时 不知道账号密码 可以字符串拼接 直接登录 或一些其他删除表等操作
比如用户输入: ' or 1=1 -- 就可以成功登录了'是跟前面输入的sql语句连接 or 1=1 当条件成立时 然后就可以成功登录 --是省略后面的 甚至可以执行删库的操作: '; drop database xxxx
防止sql注入的方法就是避免直接将用户输入的内容拼接到sql语句中
使用带参数的sql语句执行数据库操作就可以避免sql注入
使用带参数的sql语句不需要关注sql语句带引号的问题
在sql语句中 使用@xxx 定义sql参数
案列:
// 2、在SqlCommand对象中为sql参数赋值
// 添加参数的方法1(推荐)
// cmd.Parameters.AddWithValue("@abc", textBox1.Text); // 添加一个参数,并为参数赋值
// cmd.Parameters.AddWithValue("@efg", textBox2.Text);
// 添加参数的方法2
//cmd.Parameters.Add("@abc", SqlDbType.VarChar); // 添加一个参数,并指定参数的类型
//cmd.Parameters["@abc"].Value = textBox1.Text; // 为@abc参数赋值
//cmd.Parameters.Add("@efg", SqlDbType.VarChar);
//cmd.Parameters["@efg"].Value = textBox2.Text;
// 添加参数的方法3
//cmd.Parameters.Add(new SqlParameter("@abc", textBox1.Text));
//cmd.Parameters.Add(new SqlParameter("@efg", textBox2.Text));
// 添加参数的方法4(推荐)
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter("@abc", textBox1.Text),
new SqlParameter("@efg", textBox2.Text)
};
cmd.Parameters.AddRange(parameters);
封装几个类的方法
/// <summary>
/// 执行增删改操作
/// </summary>
/// <param name="sql">要执行的sql语句</param>
/// <param name="parameter">传递的sql参数</param>
/// <returns></returns>
public static int Update(string sql, params SqlParameter[] parameter)
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddRange(parameter);
return cmd.ExecuteNonQuery();
}
/// <summary>
/// 执行查询操作
/// </summary>
/// <param name="sql">要执行的sql语句</param>
/// <param name="parameter">传递的sql参数</param>
/// <returns></returns>
public static SqlDataReader GetData(string sql, params SqlParameter[] parameter)
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddRange(parameter);
return cmd.ExecuteReader();
}
/// <summary>
/// 执行单行单列的查询操作
/// </summary>
/// <param name="sql">要执行的sql语句</param>
/// <param name="parameter">传递的sql参数</param>
/// <returns></returns>
public static object GetObject(string sql, params SqlParameter[] parameter)
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddRange(parameter);
return cmd.ExecuteScalar();
}
下一节讲EF(Entity Framework) 不需要写连接字符串 因为在写字符串也很难查找报错地方因为字符串写错问题 以及连接创建许多代码 和查询等还需要注意SQL防注入