连接数据库
一、安装EF6
从NuGet安装EF6或打开终端执行以下命令,选择最新版本
Install-Package EntityFramework
二、在APP.config中配置数据库连接字符串
2.1 打开项目中的 APP.config 文件
2.2 找到 <connectionStrings> 节点,没有就手动添加
2.3 添加新的连接字符串节点
<add name="DefaultConnection" connectionString="Server=localhost;Database=YourDatabase;uid=sa;pwd=123456;"
providerName="System.Data.SqlClient" />
2.4 保存文件
三、建立数据库内的表,用于存储数据,例如人员表等
3.1 新建一个类,在类中使用属性定义表的内容,例如人员表等,并设置各种属性的类型、是否必填、是否主键等
public class Person
{
[Key]//主键
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]//自动递增
public int Id { get; set; }
[Required]//必填
[StringLength(50)]//最大长度为50
public string Name { get; set; }
[Required]//必填
[Range(0,80)]//年龄范围为0-80
public int Age { get; set; }
}
3.2 保存文件
四、建立EF操作数据库的核心类DbContext
4.1 定义一个类,继承DbContext类,实现以下方法
public class PersonDbContext : DbContext
{
//指定连接字符串名称,与APP.config中配置的连接字符串名称一致
public PersonDbContext() : base("DefaultConnection")
{
}
//对应数据库中的人员表
public Dbset<Person> persons {get;set;}
//如果有多张表,继续添加
//public Dbset<Order> orders {get;set;}
}
4.2 保存文件
五、在项目中使用EF6操作数据库
5.1 查询操作
5.1.1 查询所有人员
public class ServerHelper
{
public List<Person> GetAll()
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
// db.Persons = 人员表
// .ToList() = 查询所有数据,转成List
return db.persons.ToList();
}
}
}
//为啥使用using语句?
//因为DbContext类是可处置的,需要在使用完后释放资源,否则会导致内存泄漏
//using语句会自动调用Dispose方法,释放资源
//如果使用using语句,需要在using语句块中使用DbContext类,否则会导致资源泄漏
5.1.2 按ID查询人员
public class ServerHelper
{
public Person GetById(int id)//查询唯一,所以不使用List<Person>
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
// db.Persons = 人员表
// .Find(id) = 根据主键ID查询人员,如果不存在则返回null
// .FirstOrDefault() = 查询第一个数据
return db.persons.Find(id);
}
}
}
5.1.3 按姓名查询,模糊查询
public class ServerHelper
{
public List<Person> GetByName(string name)
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
// db.Persons = 人员表
// .Where(p => p.Name.Contains(name)) = 根据姓名包含name查询人员
// .ToList() = 转成List
return db.persons.Where(p => p.Name.Contains(name)).ToList();
}
}
}
//p=>p.Name.Contains(name)是Lambda表达式,用于查询姓名包含name的人员
5.1.4 多条件查询
public class ServerHelper
{
public List<Person> GetByNameAndAge(string name = null, int? age = null)//?表示可空参数
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
// db.Persons = 人员表
// .Where(p => p.Name.Contains(name) && p.Age == age) = 根据姓名包含name和年龄等于age查询人员
// .ToList() = 转成List
//return db.persons.Where(p => p.Name.Contains(name) && p.Age == age).ToList();
//延迟查询,将还没有执行的查询条件保存起来,等最后统一执行
var query = db.persons.AsQueryable();
//如果姓名不为空,添加姓名查询条件
if (!string.IsNullOrEmpty(name))
{
query = query.Where(p => p.Name.Contains(name));
}
//如果年龄有值,添加年龄查询条件
if (age.HasValue)
{
query = query.Where(p => p.Age == age.Value);
}
return query.ToList();//最后统一执行查询,转成List
}
}
}
5.2 新增操作
5.2.1 新增人员
public class ServerHelper
{
public bool Add(Person person)
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
// db.Persons = 人员表
// .Add(person) = 新增人员
db.persons.Add(person);
// .SaveChanges() = 保存新增数据
int result = db.SaveChanges();
//返回受影响的行数,如果大于0,说明新增成功
return result >0;
}
}
}
5.2.2 批量增加
public class ServerHelper
{
public bool AddRange(List<Person> persons)
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
// db.Persons = 人员表
// .AddRange(persons) = 批量新增人员
db.persons.AddRange(persons);
// .SaveChanges() = 保存新增数据
return db.SaveChanges() >0;
}
}
}
5.3 更新操作 先查询在更新
//先查询再更新,更安全,避免全局更新所有数据
public class ServerHelper
{
public bool Update(Person person)
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
// db.Persons = 人员表
// .Find(id) = 根据主键ID查询人员,如果不存在则返回null
// .FirstOrDefault() = 查询第一个数据
Person existingPerson = db.persons.Find(person.Id);
if (existingPerson == null)
{
//如果不存在,返回false
return false;
}
//如果存在,更新人员信息
existingPerson.Name = person.Name;
existingPerson.Age = person.Age;
return db.SaveChanges() >0;
}
}
}
5.4 删除操作 按条件删除,以姓名删除为例
public class ServerHelper
{
public bool DeleteByName(string name)
{
using (var db = new PersonDbContext())//对应上面操作数据库的核心类DbContext
{
//先查询与输入姓名相匹配的所有人员
var person = db.persons.Where(p=>p.Name==name).ToList();
//如果查询到的人员为空,说明不存在,返回false
if (person.Count == 0)
{
return false;
}
//如果存在,删除人员
db.persons.RemoveRange(person);
//返回受影响的行数,如果大于0,说明删除成功
return db.SaveChanges() >0;
}
}
}
六、使用示例
var serverHelper = new ServerHelper();
//查询所有人员
var All = serverHelper.GetAll();
//查询姓名包含name的人员
var persons = serverHelper.GetByName("张三");
//查询姓名包含name和年龄等于age的人员
var persons = serverHelper.GetByNameAndAge("张三", 18);
//单条新增
var newPerson = serverHelper.Add(new Person { Name = "张三" ,Age = 18});
//批量新增
var newPersons = serverHelper.AddRange(new List<Person>
{
new Person { Name = "张三" ,Age = 18},
new Person { Name = "李四" ,Age = 20}
});
//更新
var updatePerson = serverHelper.Update(new Person { Id = 1, Name = "张三", Age = 20 });
//删除
var deletePerson = serverHelper.DeleteByName("张三");
七、总结
- 本文介绍了C#连接数据库的其中一种方式,并不唯一
- EF是ORM(对象关系映射)框架,可以简化数据库操作,提高开发效率,对比传统的ADO.NET(数据访问技术-SqlCommand\SqlConnection),EF提供了更高级的功能,如自动映射、延迟查询、批量操作等。
- 说一下使用ADO.NET进行数据库查询时,怎么操作:
internal class SqlServerHelp
{
static string contextStr = "server=.;database=PersonDB;uid=UID;pwd=PWD";//数据库连接字符串(地址+账号密码)
static SqlConnection sqlConn = new SqlConnection(contextStr);//创建数据库连接对象(还没真正连接)
/// <summary>
/// 查询数据库
/// </summary>
/// <returns>返回查询结果的数据表</returns>
public static DataTable Select()
{
sqlConn.Open();//第一步:打开数据库连接(真正连上数据库)
SqlCommand cmd = sqlConn.CreateCommand();//第二步:创建SQL命令对象,并自动绑定当前连接
string cmdStr = "select * from 人员表";//要执行的SQL查询语句
cmd.CommandText = cmdStr;//把SQL语句交给命令对象
//cmd.ExecuteNonQuery();//执行命令但不返回数据(用于增删改,查数据不用它)
SqlDataAdapter adapter = new SqlDataAdapter(cmd);//第三步:创建数据适配器(搬运工),负责执行命令并取回数据
DataTable dt = new DataTable();//创建一个空表格,准备装数据
adapter.Fill(dt);//执行SQL,把查到的数据填充到表格中
sqlConn.Close();//第四步:关闭数据库连接(释放资源)
return dt;//返回装满数据的表格
}
}
- 使用SqlDataAdapter和SqlDataReader的区别
- SqlDataAdapter:用于批量查询,返回数据表(DataTable),适合需要处理大量数据的情况。
- SqlDataReader:用于单条查询,返回数据读取器(SqlDataReader),适合需要处理单条数据的情况。