前有ADO.NET,后有ORM模式的EntityFramework。这两种技术都实现了对数据库的访问操作。如果要说哪种技术好,就看项目架构的大小,使用者的熟练程度等等,毕竟萝卜白菜,各有所爱。

今天要记录和讨论的是项目之数据访问层中,使用EF来操作数据库,并可以自动更新数据库表的结构。闲话休提,逻辑步骤为先!

一、创建测试项目

目的:创建一个简单的带有模型层和数据访问层的控制台应用程序架构。如下图:

Model:用作模型层,对应数据库中的表;

DAL:数据访问层,实现对数据库的操作控制。引用Model;

EFDemo:一个简单的控制台应用程序。引用Model和DAL。

二、创建模型

在Model层中创建需要的模型类,模型类对应数据库中的表结构。

1、Student模型

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Model {
//指定表名
[Table("Student")]
public class Student {
//指定该表的主键
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
public string Name { get; set; }
public DateTime? BirthDay { get; set; }
public int? Age { get; set; }
}
}

可以像平常创建普通类型一样创建Student类。但是,将Student类创建完毕之后,要给这个类和类中的属性添加相应的特性约束,以便映射到数据库的表中。在添加相关特性之前,Model层需要引用System.ComponentModel.DataAnnotations这个类库,方便使用Table和Key等相关特性类型。如果需要将对应表中的字段映射为可空,那么在Student的属性类型后面加个问号(?)即可,如public Datetime? BirthDay;

三、创建数据上下文

有了数据上下文,才能在其他诸如业务逻辑层中操作数据库,当然,本次的EFDemo兼容了业务逻辑层。

接下来,我们在数据访问层(DAL)中创建数据上下文。

创建步骤:

1、查看DAL中是否包含了EntityFramework的引用,如果没有,就使用NuGet管理工具包去安装EntityFramework。

可以看见当前的DAL中,没有包含对EntityFrameword的引用。接下来,我们使用 管理NuGet程序包去添加。在这里,稍微废话一点,NuGet其实可以看做New-Get,没错,就是获取新东西的意思。NuGet是一个好东西,它就像一个图书馆,里面存放着各式各样的dll包,我们可以使用它去获取当前没有的dll文件包。

右键点击“引用”,就会看到菜单里面有一个“管理NuGet程序包(N)...”的子项,点击该菜单子项。

进入 NuGet程序包管理器 界面之后,就会看见很多程序包,而我们现在只需要EntityFramework程序包。找到EntityFramework程序包之后,点击右边界面上的“安装”按钮。

成功安装EntityFramework程序包之后的界面。如下图:

OK,创建数据上下文的先决条件已经具备。

2、创建数据上下文

在创建数据上下文之前,容我们想一下,程序是怎么知道连接哪个地址的数据库呢?通过数据库连接字符串!接下来,我们先在配置文件中创建数据库的连接字符串。需要在哪个配置文件中创建呢?不要搞错了哈,需要在应用程序的配置文件中创建连接字符串,不要在类库的配置文件中去创建哟。如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!--Begin 创建连接字符串-->
<connectionStrings>
<add name="EFDemo" connectionString="server=.;Database=EFDemo;Trusted_Connection=true;" providerName="System.Data.SqlClient" />
</connectionStrings>
<!--End 创建连接字符串-->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

接下来真正开始创建数据上下文类,如以下代码:

using Model;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DAL {
public class DemoContext:DbContext {
//使用name=EFDemo的连接字符串
public DemoContext() : base("EFDemo") { } //Students属性对应数据库中的Student表
public virtual DbSet<Student> Students { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
}
}
}

这么简单?就这么简单!

能使用该数据上下文类操作数据库了吗?能!

可是数据库中没有EFDemo数据库呢,也没有Student表呢,需要先创建吗?没那个必要,本次Demo使用的是CodeFirst(代码优先),系统会识别连接字符串中的数据库名称(Database=EFDemo)和数据上下文类型中的DbSet<Student>,通过ORM框架自动在数据库中创建并映射数据库EFDemo和表Student。这就是代码优先模式的优势,不必先创建数据库,也不必使用数据库实体创建edmx文件去映射。直接写模型类,直接创建数据上下文。剩下的事情交给EntityFramework去处理。

不过有一点需要谨记:需要使用数据上下文在应用中操作模型类,数据库才能被创建。不过,在操作模型类之前,也可以使用数据上下文的Database属性去初始化并创建数据库,如:context.Database.Initialize(true);

三、使用

1、先引用EntityFramework

在控制台应用程序中,由于需要实现对DbContext的使用,因此得先引用EntityFramework。这次引用EntityFramework不必用NuGet管理包加载。刚DAL层不是已经加载过了吗,直接到DAL项目中去引用过来就行。如下图所示:

2、在Main方法中使用

代码如下:

using DAL;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace EFDemo {
class Program {
static void Main(string[] args) { using (DemoContext context = new DemoContext()) {
//在使用模型类之前需要强制创建数据库 true:强制创建
context.Database.Initialize(true);
Student stu = new Student {
Name = "赵子成",
BirthDay = DateTime.Parse("1990-08-01"),
Age =
}; //新增一个Student实体,相当于在Student表中,新增一条数据
context.Students.Add(stu);
//保存
context.SaveChanges();
}
}
}
}

接着,我们去数据库中看看,是否已经成功创建了EFDemo数据库和Student表呢?

根据上图,我们可以看出,数据库EFDemo和Student表已经成功创建,并且Student表中已经成功被插入了一条记录。

接下来,我们实现对Student表的增删查改(CRUD)操作。

查询:

 foreach (var stu in context.Students)
Console.WriteLine("{0} {1} {2} {3}",stu.ID,stu.Name,stu.BirthDay,stu.Age);

查询结果:

修改:

                Student stu = context.Students.Where(s => s.Age == ).SingleOrDefault();
if (stu != null) {
stu.Name = "吴天野";
//设置该实体对象的状态为 修改
context.Entry(stu).State = System.Data.Entity.EntityState.Modified;
//保存
context.SaveChanges();
}

修改结果:

删除:

                //针对删除操作,只需要知道一个实体的主键就可以将之从数据库中删除
//如果不知道主键,也可以用其他方式从数据库中查出该实体的数据,从而将之删除
Guid id = new Guid("B1048903-0074-E711-970D-58FB84575557");
Student stu = context.Students.Find(id);
if (stu != null) {
//设置该实体对象的状态为 删除
context.Entry(stu).State = System.Data.Entity.EntityState.Deleted;
//保存
context.SaveChanges();
}

删除结果:

四、自动更新数据库结构

在开始之前,让我们来做一个小实验。在Model层的Student类中新增一个属性Address。如下代码:

    [Table("Student")]
public class Student {
//指定该表的主键
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
public string Name { get; set; }
public DateTime? BirthDay { get; set; }
public int? Age { get; set; } public string Address { get; set; }
}

新增完成后,运行代码试试,看能成功运行否?肯定不能!会出现如下图的异常:

这是个什么错呢?因为数据库已经被创建,但是我们在代码中修改了模型类Student的结构。这是由于该Student类的结构和数据库中Student表的结构不一致造成的。怎么解决呢?使用迁移技术。

请继续下一篇文章:EF-使用迁移技术让程序自动更新数据库表结构

EF-关于类库中EntityFramework之CodeFirst(代码优先)的操作浅析的更多相关文章

  1. EF框架搭建小总结--CodeFirst代码优先

    前言:之前在下总结编写了一篇 EF框架搭建小总结--ModelFirst模型优先 博文,看到一段时间内该博文的访问量蹭.蹭蹭.蹭蹭蹭...往上涨(实际也不是很多,嘿嘿),但是还是按捺不住内心的喜悦(蛮 ...

  2. EF框架搭建小总结--CodeFirst模型优先

    前言:之前在下总结编写了一篇 EF框架搭建小总结--ModelFirst模型优先 博文,看到一段时间内该博文的访问量蹭.蹭蹭.蹭蹭蹭...往上涨(实际也不是很多,嘿嘿),但是还是按捺不住内心的喜悦(蛮 ...

  3. C# ORM—Entity Framework 之Code first(代码优先)(二)

    一.Entity Framework Code first(代码优先)使用过程 1.1Entity Framework 代码优先简介 不得不提Entity Framework Code First这个 ...

  4. asp.net在类库中使用EF 6.0时的相关配置

    前提:之前使用EF的配置都是直接使用NuGet安装在项目中,然后直接修改web.config中的connectionString,然后创建相关dbcontext直接使用就可以了.此次为直接将EF安装在 ...

  5. 在.NET Core类库中使用EF Core迁移数据库到SQL Server

    前言 如果大家刚使用EntityFramework Core作为ORM框架的话,想必都会遇到数据库迁移的一些问题. 起初我是在ASP.NET Core的Web项目中进行的,但后来发现放在此处并不是很合 ...

  6. ASP.NET MVC项目中EntityFramework"代码优先方法"的使用步骤

    EF提供了三种方式来实现项目,分别是: (1)代码优先方法: (2)模型优先方法: (3)数据库优先方法: 本篇主要记录在Vs2010环境下使用代码优先的方式实现数据库和后端代码数据交互,语言为C#, ...

  7. 在C#代码中应用Log4Net(五)将Log4Net正确地封装在自己的类库中并进行调用

    前面的几篇文章已经比较完整地解释了怎么使用Log4Net,但是我们可能需要将Log4Net的日志类封装在自己的类库中,以便C/S或B/S程序进行调用.下面的示例程序简单地分为两层,一个是应用程序层We ...

  8. .net EF之CodeFirst代码先行(转)

    为了支持以设计为中心的开发流程,EF还更多地支持以代码为中心 (code-centric) ,我们称为代码优先的开发,代码优先的开发支持更加优美的开发流程,它允许你在不使用设计器或者定义一个 XML ...

  9. 在快速自定义的NopCommerce中使用实体框架(EF)代码优先迁移

    我看到很多nopCommerce论坛的用户问他们如何使用Entity Framework(EF)代码优先迁移来自定义nopCommerce,添加新的字段和entites核心.我实际上在做nopComm ...

随机推荐

  1. Wannafly挑战赛19 B矩阵

    矩阵 思路: 预处理好前缀和,枚举上边界和下边界,将二维变成一维,用单调队列找满足题意的最小前缀 复杂度,O(r*r*c) 代码: #pragma GCC optimize(2) #pragma GC ...

  2. C#接口实现技巧之借助第三方

    一个类继承了一个接口,对接口实现通常的做法---直接在这个类中对接口进行实现. 利用继承的概念,可以很巧妙地借助第三方类对接口进行实现,这种方式在实际的项目开发过程中其实用途很是比较大的,至少我们的游 ...

  3. linux中tar命令(打包、压缩、解压)、zip和unzip、rar多种压缩文件

    一.名词解释 打包:将一大堆文件或目录变成一个总的文件[tar命令] 压缩:将一个大的文件通过一些压缩算法变成一个小文件[gzip,bzip2等] Linux中很多压缩程序只能针对一个文件进行压缩,这 ...

  4. MySQL ICP(Index Condition Pushdown)特性

    一.SQL的where条件提取规则 在ICP(Index Condition Pushdown,索引条件下推)特性之前,必须先搞明白根据何登成大神总结出一套放置于所有SQL语句而皆准的where查询条 ...

  5. C# 读取word2003 并且显示在界面上的方法

    1.新建一个windows窗体程序 2. 引入包WinWordControl.dll 3.添加引用 4.引入组件WinWordControl组件 5.主界面上加入按钮 ,opendialog, win ...

  6. Java类成员变量的默认值

    1.布尔型(boolean)变量默认值为false,byte.short.int.long为0,字符型为'\u0000'(空字符),浮点型(float double)为0.0,引用类型(String) ...

  7. ionic this.navCtrl.push()和this.navCtrl.pop()

    在ionic中,this.navCtrl.push()和this.navCtrl.pop()都是进行页面跳转,但是用法又有区别 例如有A  B  C三个页面,三个页面都是使用this.navCtrl. ...

  8. java,sort函数的深刻理解

    先来看看题目吧: 链接:https://www.nowcoder.com/questionTerminal/97b6a49a85944650b2e3d0660b91c324来源:牛客网 [编程题]德才 ...

  9. apiCloud 调微信支付,调支付宝支付

    data里面的参数信息,需要从后台接口中调取,点击查看微信支付详情,https://docs.apicloud.com/Client-API/Open-SDK/wxPay 首先,需要在config.x ...

  10. 最长回文字串——manacher算法

    时间复杂度:O(n) 参考:https://segmentfault.com/a/1190000003914228 1.问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字 ...