一、EF概念
1.实体框架(Entity Framework)是一种对象关系映射器(O/RM),它使.NET开发人员能够通过.NET对象来操作数据库。它消除了开发人员通常需要编写的大多数数据访问代码的需求。ORM框架有个优势:解放开发人员编写数据库操作逻辑,把关注点转移到业务逻辑。提高开发效率。(开发快,节省成本。)
EF是微软官方在推广的一个重要ORM框架。
2.ORM:对象关系映射(英文全称:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种编程技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。即:把数据库中的表、视图等数据结构映射成语言中的对象。
3.EF两版本:.NET Core版本跨平台、.NET Framework只支持Window平台
ORM关系映射框架有很多,C#中比较流行的有:
N层架构、微软官方(EF框架)、国外的(Dapper、NHibernate等)、国内的(SqlSugar、Dos.ORM等)
详情网址:https://segmentfault.com/a/1190000011676744
二、EF组成
1.EF组成
a、EDM(实体数据模型 Entity Data Model): EDM包含三个主要部分——概念模型、映射、存储模型。(重要)
概念模型(entity): 概念模型包含了模型类和它们之间的关系。 这将是独立于数据库表设计。(想法)
映射(mapping): 映射由概念模型如何映射到存储模型的信息组成。(转换)
存储模型(data): 存储模型是数据库设计模型,包括表、视图、存储过程等、以及它们之间的关系和主键,外键。(设计)
b、LINQ To Entity(L2E): L2E是一种的查询实体对象的语言, 它返回在概念模型中定义的实体。 (LINQ集成查询语言)
语言集成查询(英语:Language Integrated Query)
c、Entity SQL: Entity SQL是一个类似于L2E的查询语言。 然而,它比L2E更加复杂。
d、Object Services(对象服务):对象服务是访问数据库中的数据并返回数据的主要入口点。它负责数据实例化,把Entity Client Data Provider(下一层)的数据转换成实体对象。(映射,转换)
e、Entity Client Data Provider:主要职责是将L2E或Entity Sql转换成数据库可以识别的Sql查询语句,它通过ADO.Net Data Provider向数据库发送或者索取数据。
f、ADO.Net Data Provider:使用标准的ADO.net与数据库通信。
2.EF框架中重要文件后缀:
.edmx:实体数据模型文件。entity data model
.tt:模板文件,生成模型、上下文等使用的模板文件。 template
.Context.cs 实体上下文,数据库上下文。 相当于一个数据库实例,通过实例拿到DbSet,DbSet相当于一张表中的数据。连接字符串在数据库上下文对象的构造函数中。 database set数据库集==》数据库包含很多对象的集合(很多表,很多视图,很多存储过程等), DataSet数据集(内存中的数据集,可以有很多表)
.cs 模型类文件(实体类,领域模型 Domain Model)。 相当于数据库中的表结构。导航属性===外键关系。
三、三种使用方式
数据库优先 database first(数据库已经设计好,基本不改动的情况下使用)
模型优先 model first(先设计模型,再根据模型生成数据库实体对象和相关访问数据库的代码)
代码优先 code first(推荐,先写代码,再生成数据库) (重要,推荐使用)

1.代码优先支持数据迁移,代码优先使用步骤:(重要)
a. 安装EF框架,例如下图(程序包管理控制台)命令行创建EF框架,下面出现PM>表示创建成功
注意:程序包管理控制台在工具栏的NuGet包管理器里面

b. 在当前项目中启用数据迁移,执行命令:Enable-Migrations //启用迁移

c. 添加迁移版本,执行命令:Add-Migration 版本名称 // 添加迁移文件

d. 更新数据库,执行命令:Update-Database // 根据迁移文件,更新数据库

安装EF网址:https://learn.microsoft.com/zh-cn/ef/ef6/fundamentals/install
2。PM包管理器概念? NuGet概念? 如何打开PM包管理器?如何使用PM包管理器?PM包管理器中重要命令?
PM概念:
Package Manager 包管理器,可以从NuGet上下载第三方模块包(即:类库,程序集),也可以把自己开发的模块包上传到NuGet上。
NuGet概念:
NuGet类似于手机上的“应用市场”,它提供一个平台,供开发者上传,下载其他开发者分享的模块包。
3.代码优先步骤
3.1打开PM包管理器:
工具==》NuGet包管理器==》程序包管理器控件台
包管理器中重要的命令:
Install-Package 模块包名称 //安装程序集
Uninstall-Package 模块包名称 //卸载程序集
a. Install-Package EntityFramework 安装最新版实体框架 (一次性)
b. 编写代码(更改:反复修改,添加,删除代码)
b.1. 编写实体模型类(Models类文件夹)(Domain Class领域模型类 POCO)
b.2. 编写数据库上下文(Context文件夹)
b.3. 把上下文和真实的数据库建立连接
c. 执行迁移命令(重新生成数据库表结构)
Enable-Migrations //启用迁移(一次性)
Add-Migration InitialCreate //添加迁移(生成创建数据库及数据库表的代码),其中:InitialCreate是版本名称
Update-Database //更新数据库(把Add-Migration生成的代码执行一下,把领域模型的结构同步到数据库中)
总结: 1.安装EF(entityframework)
2.创建文件夹
1.models
2.contexts(上下文)
2.1定义一个数据库test的实体类TestEntities
2.2TestEntities必须继承DbContext
2.3定义构造函数,指定数据库连接的字符串
2.4定义数据集



注意:迁移命令使用细节:
1。领域模型发生变化(添加新模型,修改已存在的模型,删除了模型),必须进行迁移和更新。
2。上一次迁移没有更新到数据库,不能生成下次迁移。

Add-Migration InitialCreate //添加迁移 完成后产生下图的迁移文件

4.详细代码优先案例
//App.config里内容
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="ConnString"
connectionString="server=.;database=MyDataBase;User ID=sa;Password=123456;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
//Models文件夹内User类里代码
namespace MYN_daimayouxian68.Models
{
public class User
{
public int UserId { get; set; }
public string Account { get; set; }
public string Password { get; set; }
}
}
//Context文件夹里TestEntities类里的代码
using MYN_daimayouxian68.Models;
using System.Data.Entity;
namespace MYN_daimayouxian68.Contexts
{
public class TestEntities:DbContext
{
public TestEntities() : base("name=ConnString")
{
}
public virtual DbSet<User> Users { get; set; }
}
}
From1设计图

//from1内的代码,实现数据库的增删改查
using MYN_daimayouxian68.Contexts;
using MYN_daimayouxian68.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Windows.Forms;
namespace MYN_daimayouxian68
{
public partial class Form1 : Form
{
int page=1;
int pageSize = 3;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
BindDataGridView();
}
private void BindDataGridView()
{
using (var context = new TestEntities())
{
var list = context.Users
.Where(s => s.Account.Contains(textBox1.Text))
.OrderByDescending(s => s.UserId)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToList();
dataGridView1.DataSource = list;
}
}
private void btnQuery_Click(object sender, EventArgs e)
{
BindDataGridView();
}
private void btnAdd_Click(object sender, EventArgs e)
{
using (var context = new TestEntities())
{
//context.Users.Add(new Models.User() { Account = "admin", Password = "123456" });//添加一条
List<Models.User> list = new List<Models.User>
{
new Models.User{Account="test",Password="123456"},
new Models.User{Account="aaaa",Password="123456"}
};
context.Users.AddRange(list);//添加多条
context.SaveChanges();//保存数据,必须写否则数据库中不存在增删改查的内容
}
BindDataGridView();
}
private void btnDelete_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count != 1)
{
MessageBox.Show("请选择一条数据删除!");
return;
}
int userId = Convert.ToInt32(dataGridView1.SelectedRows[0].Cells["UserId"].Value);
using (var context = new TestEntities())
{
var model = context.Users.FirstOrDefault(x => x.UserId == userId);
context.Users.Remove(model);
context.SaveChanges();
}
BindDataGridView();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count != 1)
{
MessageBox.Show("请选择一条数据修改!");
return;
}
int userId = Convert.ToInt32(dataGridView1.SelectedRows[0].Cells["UserId"].Value);
using (var context = new TestEntities())
{
var model = new User()
{
Account = "KKKK",
Password = "123456",
UserId=userId
};
context.Entry(model).State = EntityState.Modified;
context.SaveChanges();
}
BindDataGridView();
}
private void btnNext_Click(object sender, EventArgs e)
{
page++;
BindDataGridView();
}
private void btnPrv_Click(object sender, EventArgs e)
{
page--;
BindDataGridView();
}
}
}
5.数据库优先步骤
a.安装EF框架(手动安装,用管理NuGet包)
项目引用右键=》管理NuGet包=》浏览搜索EntityFramework

b.添加实体数据模型(如下图)

c.选择数据库优先

注意:

6.数据库优先From代码

//From1代码
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Windows.Forms;
namespace MYN_database68
{
public partial class Form1 : Form
{
int page = 1;
int pageSize = 3;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
BindDataGridView();
}
private void BindDataGridView()
{
using (var context=new MYNEntities())
{
List<Student> list1 = context.Student
.Where(s => s.StudentName.Contains(textBox1.Text))
.Where(s => s.Status == 0)
.OrderByDescending(s => s.StudentId)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToList();
IQueryable<Student> list2 = from s in context.Student
orderby s.StudentId descending
select s;
dataGridView1.DataSource = list1;
}
}
private void btnQuery_Click(object sender, EventArgs e)
{
BindDataGridView();
}
private void btnAdd_Click(object sender, EventArgs e)
{
using (var context=new MYNEntities())
{
var model = new Student()
{
StudentName="XXX",
Sex=false,
Status = 0,
Birthday=DateTime.Now
};
context.Entry(model).State = EntityState.Added;
context.SaveChanges();
}
BindDataGridView();
}
private void btnDelect_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count!=1)
{
MessageBox.Show("请选择一条删除!");
return;
}
int studentId = Convert.ToInt32(dataGridView1.SelectedRows[0].Cells["StudentId"].Value);
using (var context = new MYNEntities())
{
var model = context.Student.First();
var model1=context.Student.FirstOrDefault(s=>s.StudentId==studentId);
var model2=context.Student.Single(s=>s.StudentId== studentId);
var model3=context.Student.SingleOrDefault(s=>s.StudentId == studentId);
context.Entry(model).State = EntityState.Deleted;
// context.Student.Remove(model1);
context.SaveChanges();
}
BindDataGridView();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count != 1)
{
MessageBox.Show("请选择一条修改!");
return;
}
int studentId = Convert.ToInt32(dataGridView1.SelectedRows[0].Cells["StudentId"].Value);
using (var context = new MYNEntities())
{
var model = new Student()
{
StudentName = "KKKK",
Sex = false,
Birthday = DateTime.Now,
Status = 0
};
context.Entry(model).State = EntityState.Modified;
// context.Student.AddOrUpdate(model);
context.SaveChanges();
}
BindDataGridView();
}
private void btnNext_Click(object sender, EventArgs e)
{
page++;
BindDataGridView();
}
private void btnPrv_Click(object sender, EventArgs e)
{
page--;
BindDataGridView();
}
}
}
增删改通用方法,只用修改一个API即可,例如添加



四、EF框架拓展网址
实体框架:
https://blog.csdn.net/2302_77639120/article/details/142082970
https://www.cnblogs.com/wyy1234/p/9650759.html
https://learn.microsoft.com/zh-cn/ef/ef6/
EF三种使用方式对比:
https://www.cnblogs.com/wfy680/p/11969505.html
代码优先:
https://download.csdn.net/blog/column/7504784/84750516
https://learn.microsoft.com/zh-cn/ef/ef6/modeling/code-first/workflows/new-database
代码注解:
https://blog.csdn.net/ultramand/article/details/130039001
https://learn.microsoft.com/zh-cn/ef/ef6/modeling/code-first/data-annotations
1万+

被折叠的 条评论
为什么被折叠?



