基础概念与Database First
基本概念
EntityFramework是微软推出的一款ORM工具,关于ORM的概念请参考博客https://www.cnblogs.com/huanhang/p/6054908.html。这篇文章对ORM进行很详细的介绍。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。
在.NET3.5之前我们从数据库检索或者存储数据的方式经常都是ADO.NET。操作数据会经历如下步骤,打开数据库连接,创建一个数据集来获取或提交数据到数据库,将数据集中的数据转换为.NET对象。或者反过来应用业务规则。这是一个繁琐且重复的工作,或许会有一些Helper来帮助我们解决数据库连接方面的工作,但是数据集到领域对象的过程是我们需要一次次去映射的。所以,ORM工具就提供给了我们操作业务对象,由ORM对我们操作的对象进行数据库操作映射。EntityFramework就是这样的一种工具,我们使用Linq操作领域对象,EntityFramework会帮我们将对应操作转换为SQL语句,然后连接到数据库执行。这样我们就可以在更高的抽象层面来处理数据,并且与传统应用程序相比,可以用更少的代码创建和维护面向数据的应用程序。关于EntityFramework的概念和介绍可以参考MSDN或者http://www.entityframeworktutorial.net/what-is-entityframework.aspx。以上部分概念也来源于此网站。另外,EntityFramework Core为EF垮平台版本。好了,下面进入EntityFramework的具体使用部分。
EntityFramework的3中使用模式
EntityFramework有3中使用模式
DataBase First:从数据库开始,在数据库已经存在的情况下。通过数据库结构构建实体映射对象,并生成映射元数据
Model First:使用EntityFramework提供给的模型创建工具创建数据模型与映射元数据,通过这些元数据信息创建数据库
Code First:通过DDD创建领域对象并配置映射规则,数据迁移规则。EF会根据领域对象模型与映射规则来创建数据库
下面我们依次来看看3种模式在实际的编码过程中怎么使用,示例程序使用SQL Server2016数据库引擎,Northwind数据库。开发工具为VS2017。
1 Database First数据模型定义
1,创建控制台应用Demo.DatabaseFirst
2,安装EntityFramework Nuget包,示例程序版本为6.2.0
2
3,添加实体数据模型,在Data模板下选择ADO.NET实体数据模型,命名为DemoModel
image
4,因为我们是从数据库生成实体数据模型,所以,我们选择来自数据库的EF设计器
image
5,进行数据库配置,由于我这里之前配置过数据库,所以会有之前的连接信息,此处,我们新建数据库连接,点击新建连接
image
6,配置数据连接,并选择数据库。在高级选项中,有关于连接配置的选项,可以根据需要修改。
image
7,配置完成后,点击下一步选择需要生成实体数据模型的表(视图,存储过程或者函数)
image
8,点击完成,此时,从数据库映射的实体数据模型已经生成。我们可以看一下,在解决方案结构中,EF帮我们新建了哪些文件,在配置文件中又帮我们加入了哪些内容
image
DemoModel.edmx就是EF帮我们生成的数据模型,双击之后,我们可以看到我们选中的表已经映射成为了实体数据模型。生成模型的规则是EF定义的模板文件(XXX.tt),不同的EF版本有不同的模板文件,我们也可以自定义模板文件。我们右键点击某个模型,可以看到如下图的菜单。从数据库更新模型,当数据库发生更改的时候,我们可以通过点击此菜单来将数据库的更改映射到模型。表映射可以查看实体数据类型与表的映射,属性与列信息的映射信息等等。我们也可以查看数据模型的属性,在空白处点击右键,选择属性。可以看到数据模型的选项,有数据库的连接字符串信息,是否延迟加载等等,可以根据需求自行更改配置。
image
实体关系:从edmx设计中可以看到,实体之间的连接线有1…,…*,0…1的关联属性,这些关系实际上映射的就是数据库中表之间的关系,也就是我们常说的,一对一,多对多,一对多。实体数据模型会根据数据库中的主外键信息自动生成关系模型数据。选中连接线,右键查看属性,可以查看实体之间关系的具体信息。
导航属性:上面说了,实体与实体之间是存在关系的,那么怎么从一个实体去访问另外一个与他有关系的实体呢,实际上我们通过导航属性。导航属性实际上就是实现了从一个实体到另一个关联实体的访问机制。
实体数据模型实际上包含了实体对象信息,数据库元数据信息,对象与数据库的映射信息。那么这些信息是在哪里定义的呢,我们使用文本编辑工具打开DemoModel.edmx文件,可以看到edmx实际上是一个xml文件,这个xml文件的主要节点如下
image
1,edmx:StorageModels(逻辑层SSDL):SSDL主要定义了数据库中表,列,关系,视图,函数等
2,emdx:ConceptualModels(概念层CSDL):CSDL主要定义了数据模型的实体类型,这些实体暴露给上层来操作实体数据
3,edmx:Mappings(映射层):SSDL与CSDL之间的关系映射
2 Database First数据模型操作
EntityFramework使用了上述的xml文件定义了,实体,数据库对象,与他们之间的关系。至此,我们完成了EntityFramework的实体数据映射并分析了基本原理。定义数据模型的意义在于操作数据,下面我们使用数据模型来进行数据的增删改查。我们新建类CategoryServices,并添加AddCategory,UpdateCategory,DeleteCatetory,GetCatetories四个方法
2.1增加数据
复制代码
public bool AddCategory(Category category)
{
using (NorthwindEntities context = new NorthwindEntities())
{
context.Categories.Add(category);
return context.SaveChanges()>0;
}
}
复制代码
2.2修改数据
复制代码
public bool UpdateCategory(Category category)
{
bool reuslt = false;
using (NorthwindEntities context = new NorthwindEntities())
{
Category currentCategory = context.Categories
.FirstOrDefault(parm => parm.CategoryID == category.CategoryID);
if (currentCategory != null)
{
currentCategory.Description = category.Description;
reuslt = context.SaveChanges() > 0;
}
return reuslt;
}
}
复制代码
2.3删除数据
复制代码
public bool DeleteCatetory(int id)
{
bool reuslt = false;
using (NorthwindEntities context = new NorthwindEntities())
{
Category currentCategory = context.Categories
.FirstOrDefault(parm => parm.CategoryID == id);
if (currentCategory != null)
{
context.Categories.Remove(currentCategory);
reuslt = context.SaveChanges() > 0;
}
return reuslt;
}
}
复制代码
2.4查询数据
复制代码
public List GetCatetories()
{
using (NorthwindEntities context = new NorthwindEntities())
{
return context.Categories.ToList();
}
}
复制代码
调用代码
复制代码
class Program
{
static void Main(string[] args)
{
CategoryServices services = new CategoryServices();
List<Category> categories = services.GetCatetories();
categories.ForEach(parm => Console.WriteLine($"{parm.CategoryName}---{parm.Description}"));
Console.WriteLine("---select---");
Category category = new Category
{
CategoryName = "Microsoft",
Description = "this is Microsoft"
};
bool result = services.AddCategory(category);
Category categoryAdd = services.GetCatetories().LastOrDefault();
Console.WriteLine($"{categoryAdd.CategoryName}---{categoryAdd.Description}");
Console.WriteLine("---add---");
Category categoryUpdate = new Category
{
CategoryID = categoryAdd.CategoryID,
CategoryName = "Microsoft",
Description = "this is Microsoft update"
};
bool updateResult = services.UpdateCategory(categoryUpdate);
Console.WriteLine($"{categoryUpdate.CategoryName}---{categoryUpdate.Description}");
Console.WriteLine("---update---");
int catetoryId = categoryAdd.CategoryID;
bool deleteUpdate = services.DeleteCatetory(catetoryId);
Category categoryLast = services.GetCatetories().LastOrDefault();
Console.WriteLine($"{categoryLast.CategoryName}---{categoryLast.Description}");
Console.WriteLine("---delete---");
Console.ReadLine();
}
}
复制代码
执行结果
如下图执行结果,第一步我们打印了所有的Category,第二步我们添加一条Category,紧接着我们修改了添加的这条数据,最后我们删除这条数据。可以看到,增删改查操作完成。是不是感觉操作数据库也可以像操作对象一样简单,便捷。
image
数据操作基本概念
DbContext:上面的实例中,我们实例化了类型NorthwindEntities。这个在我们配置数据库连接的时候输入的上下文名称。实际上,在EntityFramework帮助我们生成数据模型时,也同时帮我们生成了继承与DbContext类型的数据上下文,我们这里是NorthwindEntities。那么数据上下文是什么呢。数据上下文实际是真实与数据库交互的桥梁。前面的章节我们定义了对象,数据,映射,这些都是基础设施,也是基础结构。在操作数据时,比如添加数据。最终数据库能执行的操作只会是SQL语句,存储过程等。所以 ,数据上下文监测了我们对实体类型的更改,在调用SaveChange时将我们对上下文中实体的更改转换成SQL语句发送给数据库执行,我们可以打开SQL Server监视工具来查看EntityFrameworkSaveChange后生成的SQL语句。所以,在了解了ORM的核心概念后,其实,如果我们愿意,也可以自己实现一套ORM工具。
image
下面的代码就是EntityFramework生成的继承自DbContext的数据上下文。
复制代码
namespace Demo.DatabaseFirst
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class NorthwindEntities : DbContext
{
public NorthwindEntities()
: base("name=NorthwindEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<CustomerDemographic> CustomerDemographics { get; set; }
public virtual DbSet<Customer> Customers { get; set; }
public virtual DbSet<Employee> Employees { get; set; }
public virtual DbSet<Order_Detail> Order_Details { get; set; }
public virtual DbSet<Order> Orders { get; set; }
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<Region> Regions { get; set; }
public virtual DbSet<Shipper> Shippers { get; set; }
public virtual DbSet<Supplier> Suppliers { get; set; }
public virtual DbSet<Territory> Territories { get; set; }
}
}
复制代码
好了,至此,EntityFramework的基本概念和Database First基本操作已经完成,由于水平有限,如果在讲解过程中有任何错误请留言告知,在学习与记录的过程与大家共同进步。下一篇会讲解EntityFramework的Model First。
郑州不孕不育医院:http://yyk.39.net/zz3/zonghe/1d427.html/郑州不孕不育医院哪家好:http://yyk.39.net/zz3/zonghe/1d427.html/
郑州不孕不育医院排名:http://yiyuan.120ask.com/zzbyby/
沈阳市哪里看胃病好www.sdgc120.com沈阳市哪里胃病治得好www.202sdgc.com沈阳市哪里治胃病最好www.201sdgc.com
沈阳哪里看胃权威www.120sdwc.com 沈阳哪看胃病比较好www.sysdjk99.com沈阳哪家医院治胃治 www.sdgc024.com
沈阳那家医院治胃病比较好http://jbk.39.net/yiyuanzaixian/shxkwckyy/
烟台哪里看胃权威www.ytxbyy.com 烟台哪里检查胃病最好www.ytwcbyy.com 烟台治疗胃胀哪家好www.ytsgcyy.com
烟台什么医院治疗胃病好www.ytdcyy.com 烟台什么地方看胃疼好www.0535wc.com 烟台那家医院看胃疼便宜www.ytdcwcyy.com
烟台那家医院看胃疼好 www.ytzcyy.com 烟台那家医院治胃病比较好www.ytswcyy.com
烟台那家医院治胃病比较好http://jbk.39.net/yiyuanzaixian/ezamyy/
- 用Python做证券指数的三种策略分析
- 明确告诉你,眼界不够,JS再好也成不了好前端
- 手把手教你整合最优雅的SSM框架
- WCF后续之旅(9):通过WCF的双向通信实现Session管理[上篇]
- 周末小贴士之“什么是语法糖”?有啥意义?
- Java反射机制深入详解
- 由for V.S. for each想到的
- 日调度5万亿次,腾讯云微服务架构体系TSF深度解读
- sed的粉丝
- 在Managed Code通过Google Gmail发送邮件以及如何通过Outlook配置Gmail
- 平方根的C语言实现(一) —— 浮点数的存储
- 用awk写递归
- bc计算A股上市新股依次涨停股价
- ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Yii框架Session与Cookie使用方法示例
- laravel 实现登陆后返回登陆前的页面方法
- Laravel 登录后清空COOKIE的操作方法
- 使用laravel和ajax实现整个页面无刷新的操作方法
- Laravel 读取 config 下的数据方法
- PHP实现数组根据某个字段进行水平合并,横向合并案例分析
- laravel框架上传图片实现实时预览功能
- PHP 多进程与信号中断实现多任务常驻内存管理实例方法
- Yii 框架控制器创建使用及控制器响应操作示例
- laravel-admin 实现给grid的列添加行数序号的方法
- Laravel 自动生成验证的实例讲解:login / logout
- 关于Laravel-admin的基础用法总结和自定义model详解
- 解决Laravel5.2 Auth认证退出失效的问题
- php输出文字乱码的解决方法
- laravel-admin表单提交隐藏一些数据,回调时获取数据的方法