前有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. python+kafka,从指定位置消费数据

    # @staticmethoddef get_kafka_reviews(self): # print type(self.bootstrap_servers) consumer = kafka.Ka ...

  2. 雷林鹏分享:XML 验证

    XML 验证 拥有正确语法的 XML 被称为"形式良好"的 XML. 通过 DTD 验证的XML是"合法"的 XML. 形式良好的 XML 文档 "形 ...

  3. java控制流

    目录 1.引用数据类型 2.流程控制语句 2.1 条件控制语句if 2.2 if语句与三元运算符的互换 2.3 循环语句 2.4 循环嵌套 2.5 跳转语句 2.6 选择结构switch 3.猜数字案 ...

  4. Music in Car CodeForces - 746F (贪心,模拟)

    大意: n首歌, 第$i$首歌时间$t_i$, 播放完获得贡献$a_i$, 最多播放k分钟, 可以任选一首歌开始按顺序播放, 最多选w首歌半曲播放(花费时间上取整), 求贡献最大值. 挺简单的一个题, ...

  5. World Tour CodeForces - 667D (bfs最短路)

    大意: 有向图, 求找4个不同的点ABCD, 使得d(A,B)+d(D,C)+d(C,A)最大

  6. 轻量级RPC

    ①自定义一个协议接口继承VersionedProtocol ②自定义协议类实现上面的接口,完善功能需求 ③服务端 ④客户端 二:模拟一个namenode

  7. git 恢复误删的分支

    在使用git的过程中,因为人为因素造成分支(commit)被删除,可以使用以下步骤进行恢复. 首先用以下步骤创建一个新分支,修改一些文件后删除,以便进行恢复. 1.创建分支 abc git branc ...

  8. MySql(九)索引

    一.索引的介绍 数据库中专门用于帮助用户快速查找数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取. 二 .索引的作用 约束和加速查找 三.常见的几 ...

  9. CSS知识点(一)

    一.引入CSS样式(重点掌握) 行内样式 内接样式 外接样式 3.1 链接式 3.1 导入式 css介绍 现在的互联网前端分三层: HTML:超文本标记语言.从语义的角度描述页面结构. CSS:层叠样 ...

  10. Android Studio build gradle project info 卡主不动解决方法.

    项目里的: build.gradle 依赖 的gradle 版本 在每个项目里 gradle/wrapper/properties/gradle-wrapper.properties 配置文件里 用户 ...