博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EF实体框架之CodeFirst一
阅读量:6993 次
发布时间:2019-06-27

本文共 4281 字,大约阅读时间需要 14 分钟。

对于SQL Server、MySql、Oracle等这些传统的数据库,基本都是关系型数据库,都是体现实体与实体之间的联系,在以前开发时,可能先根据需求设计数据库,然后在写Model和业务逻辑,对于Model类基本都是和表的字段对应着,而表中存的每条记录又和类的实例对象对应着,有了这个对照关系,就是能不能只在一边设计,在数据库设计表或在VS中设计Model,然后直接生成另一边,这样就省了好多时间成本。于是有了ORM,Object Relation Mapping,对象关系映射。既然可以根据Model可以生成数据库,数据库也可以生成Model,Model、数据库又是分离的,我们也可以根据Model生成不同类型(Sql Server\Oracle)数据库,而不同类型的数据库(Sql Server\Oracle)也可以生成同样的Model,而它们共同的纽带就是Mapping。

EF实体框架有3种类型,Data First、Model First、Code First。从今天起,将来的几篇博客可能都是关于Code First的,可能有人会问,其他的呢?对于另外两个我不打算花太多的时间,现在code first用的比较多,而且和其他两个比来说更加方便简单,code first没有包含CSDL(Conceptual Schema Definition Language 概念架构定义语言)、SSDL(Store Schema Definition Language存储架构定义语言)、MSL(Mapping Specification Language 映射规范语言)的映射定义,可是使用基于约定的映射。例如主键,只需要用Id命名属性或以Id结尾,这种会自动映射到主键上。对于上面的CSDL、SSDL、MSL根据中文应该也能猜出一二来,其实CSDL概念架构定义语言,定义概念的嘛,当然是定义.Net类的,而SSDL存储架构定义,既然是存储,肯定是数据库啊,所以它是描述表及其关系的结构。而MSL映射规范语言,当然是用来映射的,比如类中的Name属性可能在数据库定义的列名不是name,那怎么办呢?这时有了MSL就好办了,它就是用来描述映射关系的。

上面瞎逼逼半天,实际上今天是想大致演示下code first的用法,做简单的增删改查。

一、Model

首先是创建了一个控制台应用程序EFCodeFirstDemo,又创建了一个存放Model的类库EFCodeFirstModels,以及一个与数据库有关系的类库EFCodeFirstDataAccess,算是三层架构中的DAL,至于BLL先不创建,只是简单的演示。既然是code first,管理对象,那肯定要先有一个Model类,这里在EFCodeFirstDemo中定义了一个Student类。在Student类中使用约定定义StuId为主键,由于默认会把Id结尾的属性作为主键,所以不用特性也可以。

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using System.Text;using System.Threading.Tasks;namespace EFCodeFirstModels{    public class Student    {        [Key]        public string StuId { get; set; }        public string Name { get; set; }        public int Age { get; set; }        public Student(string stuId, string name, int age)        {            this.StuId = stuId;            this.Name = name;            this.Age = age;        }        //定义无参数的构造函数主要是因为在通过DbSet获取对象进行linq查询时会报错        //The class 'EFCodeFirstModels.Student' has no parameterless constructor.        public Student() { }    }}

二、DbContext数据库上下文

DbContext数据库上下文,定义了从实体对象到数据库的映射,从数据库中检索数据,就要使用它。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data.Entity;using EFCodeFirstModels;using System.Configuration;namespace EFCodeFirstDataAccess{    public class EFCodeFirstDbContext:DbContext    {                public EFCodeFirstDbContext():base("name=MyStrConn")        {           }        public DbSet
Students { get; set; } }}

在使用DbContext时要先通过NuGet添加EntityFramework,在类中引入System.Data.Entity,像上面的代码中我们给DbContext指定了数据库连接字符串,名字是MyStrConn,我们可以看下DbContext类的构造函数.

上面提供了几种构造函数,今天主要看下第一个传nameOrConnectionString和无参数的。如果不传参数,它会自定将数据库的名字命名为类库名.类名,像上面的如果不使用无参数的构造函数会创建一个名为EFCodeFirstDataAccess.EFCodeFirstDbContext的数据库。而我们的demo中是使用了参数的,参数的名是nameorConnectionString,注意是or那意味着有两种情况,一种是name,一种是ConnectionString,在上面的参数是"name=XXX",这种是ConnectionString,既然是ConnectionString,那肯定有连接字符串,在哪呢?我开始是写在了EFCodeFirstDataAccess类库中,可以始终报错,报初始化的错误,正确的是写在控制台应用程序中的配置文件中,在配置文件App.config中添加结点。这里也要注意是要提供providerName,而且configSections必须是configuration的第一个结点,我刚才把connectionStrings添加到第一个也是提示错误。

我们也可以不使用ConnectionString,而是直接复制数据库名,它会先找配置文件对于的连接字符串,如果未找到,则以它自己命名。

三、简单操作

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using EFCodeFirstModels;using EFCodeFirstDataAccess;namespace EFCodeFirstDemo{    class Program    {        static void Main(string[] args)        {            //using能及时释放资源,例如数据库连接异常,可以即使将上下文释放            using (var db=new EFCodeFirstDbContext())            {                Student stu = new Student("0001", "cuiyanwei", 25);                db.Students.Add(stu);                db.SaveChanges();                string name= db.Students.Select(p => p.Name).FirstOrDefault().ToString() ;                Console.WriteLine(name);                Student stu1 = db.Students.Where(p=>p.StuId=="0001").FirstOrDefault() ;                stu1.Name = "CYW";                db.SaveChanges();                name = db.Students.Select(p => p.Name).FirstOrDefault().ToString();                Console.WriteLine(name);                           }            Console.ReadLine();                    }    }}

在上面代码中,主要是先新增一个Student对象然后插入数据库,打印输出此时的name,然后通过数据库上下文找到StuId=0001的学生,将name更改为CYW,

保存到数据库再次打印数据name,从打印结果我们可以看到name最后是CYW,数据库中最后的结果也是CYW。通过Profiler也能查看到sql执行的过程。

 

转载地址:http://webvl.baihongyu.com/

你可能感兴趣的文章
IO流文件拷贝性能对比
查看>>
mac下更新自带的PHP版本到5.6或7.0
查看>>
Oracle——10用户自定义函数
查看>>
修复jquery.treeview的增加子节点的方法的bug
查看>>
硬盘空间满导致mysql ibd文件被删后提示Tablespace is missing for table 'db_rsk/XXX"
查看>>
Scala之初步认识与环境准备
查看>>
JFinal跨域方法的两种实现
查看>>
数据库根据字段模糊查询的思路
查看>>
基于IOS上MDM技术相关资料整理及汇总
查看>>
HBase新建表报错 org.apache.hadoop.hbase.TableExistsException
查看>>
微信小程序教程、微信小程序开发资源下载汇总(6.16日更新,持续更新中……)...
查看>>
解决eclipse莫名其妙退出问题
查看>>
MySQL mysqli_connect() 不能连接数据库问题
查看>>
基于ceph rbd+corosync+pacemaker HA-NFS文件共享
查看>>
知识的梳理计划
查看>>
使用 Smart Security 实现安全控制
查看>>
打造高效研发团队 (3) —— 绩效考核篇
查看>>
MyEclipse中为导入的jar包添加java原文件,可以直接查看java源码
查看>>
java jvm信息查询工具jinfo
查看>>
成为Java GC专家(4) — Apache的MaxClients参数详解及其在Tomcat执行F
查看>>