一、EF(Entity Framework)简介
1.ORM:Object Relation Mapping,用操作对象的方法来操作数据库
2.ORM工具有很多:Dapper、PetaPoco、NHibernate,其中用的最多的还是微软官方的Entity Framework
3.EF底层仍然是对ADO.Net的封装。EF支持SQLServer、MySQL、Oracle等主流数据库
4.使用EF进行数据库开发的时候有两个步骤需要创建:一个是数据库,另一个是模型类。根据这两种创建的先后顺序有EF的三种创建办法:
a).DataBase First(数据库优先):先创建数据库表,然后自动生成EDM文件,EDM文件生成模型类。
b).Model First(模型优先):先创建Edm文件,Edm文件自动生成模型类和数据库
c).Code First(代码优先):自己写模型类,然后自动生成数据库。没有Edm文件。
DataBase First简单、方便,但是当项目打了之后会非常痛苦;Code First入门门槛高,但是适合大项目。虽然有三种创建方法,一旦创建好了数据库、模型类之后,后面的用法都是一样的。业界推荐使用Code First,新版的EF中只支持Code irst,所以在以后的使用中,就按照Code First的方法创建使用EF。
其中EF像ASP.Net MVC一样,采用的也是"约定大于配置"的设计原则,省去了很多的配置,能用约定就不要自己配置。
二、EF的初步使用
1.安装EntityFramework
通过使用程序包管理器控制器:Install-Package EntityFramework
2.EF模型的有两种配置方式:分别为DataAnnotations、FluentAPI两种。其中DataAnnotations这种方式比较方便,但是耦合度太高,不适合大型项目开发的要求;FluentAPI这种方式在以后是经常使用。
2.1 DataAnnotations方式配置EF:
2.1.1 在安装好EF后,web.config配置文件自动帮我们配置了EF的相关配置,接下来就是写字符串连接数据库。
<connectionStrings>
<add name="conn1" connectionString="Data Source=数据库地址;Initial Catalog=数据库名称;Integrated Security=True;" providerName="System.Data.SqlClient"/>
</connectionStrings>
注意:在配置数据库连接字符串中,一定要写在<configSections>节点之后,不然会提示报错的,并且一定要添加 providerName="System.Data.SqlClient",不然会出现以下错误:
2.1.2 创建表T_Persons,创建实体类Person
[Table("T_Persons")] public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
实体类中的主键名字必须为Id,创建的类的字段名与数据库里的表列名一致,这样就可以使表和实体类产生自动映射关系了。当然,如果主键名和模型类的名字不一致,在实体类的主键属性上面添加[Key],这样就可以产生映射关系了,如果其他属性与表中列名不一致,就要用[Column("Name")]来指定。实体类名字和表名不一致,使用[Table("表名")]来指定。
必填字段标注[Required]、字段长度[MaxLength(5)]、可空字段用 int?、如果字段在数据库中有默认值,则要在属性上标注[DatabaseGenerated]。
另外注意实体类都要写成public。
2.1.3 创建DbContext类
{ public MyDbContext():base("name=conn1") { //name=conn1表示使用连接字符串中名字为conn1的取去连接字符串 } public DbSet<Person> Persons { get; set; } }
其中该类必须继承DbContext类,必须要写构造函数,同时,如果有多少个实体类,该类就有多少个DbSet<T>数据类型的属性。
2.1.4 使用EF操作数据库(添加一个数据)
//第一步:new一个DbContext类的子类 MyDbContext mdt = new MyDbContext(); //第二步:new一个实体类 Person p1 = new Person(); p1.Name = "张三"; p1.Age = 22; //第三步:将数据保存到数据库中 mdt.Persons.Add(p1); mdt.SaveChanges();
注意:MyDbContext对象是否需要using有争议,不using也没事,。每次用的时候new一个MyDbContext对象就行,不用共享,共享反而会有问题。在EF的开发团队都要说要using DbContext类,当然能如果不using的话,使用LazyLoad,但是这样做使违反分层原则的。
如果发生了数据错误,可能就出现在SaveChanges上面。
2.2.1 使用FluentAPI配置方式
和DataAnnotations配置方式的2.1.1,2.1.2步骤一致,故不再描述
2.2.3 创建DbContext类
和DataAnnotations中的DbContext类略微的不同,重写了OnModelCreating方法
public class MyDbContext:DbContext { public MyDbContext():base("name=conn2") { } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //从某个程序集中加载所有继承自EntityTypeConfiguration类到配置中 modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); } }
2.23 创建实体类的配置类
public class StudentConfig:EntityTypeConfiguration<Student> { public StudentConfig() { this.ToTable("T_Students"); //代表和数据里的T_Students表进行映射 } }
这个类是每创建一个实体类,就跟随的创建一个配置类
2.24 此时操作数据库
三、使用EF实现增删查改
在上面的例子中已经实现了增加数据,接下来就实现删,查,改
3.1 删
var getStu = md.Students.Where(s => s.Id == 2).SingleOrDefault(); md.Students.Remove(getStu); md.SaveChanges(); Console.WriteLine("删除成功!");
3.2 查
var allStudents = md.Students.Where(s => s.Id >= 1); foreach (var student in allStudents) { Console.WriteLine(student.Id); }
3.3 改
var stu=md.Students.Where(s => s.Id == 3).SingleOrDefault(); stu.Name = "李四"; stu.Age = 12; md.SaveChanges();
总结:增删查改就是操作继承DbContext类的子类,获取数据进行操作,组后调用SaveChanges()方法进行保存