Entity Framework是微软官方提供的一个ORM解决方案,它有纯正的血统,比NHibernate更容易使用并且与现有其它官方框架配合更加密切。

时代不断的在发展变化,记得10年前还是ADO(配合ASP)的天下,后来微软推出了ADO.NET,再后来推出了ADO.NET Entity Framework,可见微软在.NET与数据库交互领域的作为。

下面我将以Entity Framework(简称EF)来演示一下在C#当中如何使用好这个非常“爽”的ORM工具。我们以大家比较熟悉的模型—学生和课程的多对多的关系(学生可以选择多门课程、课程有可能有多个学生选择)来进行演示。

第一步,建立一个控制台应用程序,起名为CodeFirstEF。我们简单一点,尽量不参杂到其它技术来进行演示,将学习难度降低到最低。

建立一个控制台应用程序没有什么好说的,这里想简单的提一下,使用EF有3种常用的模型,Database-First(数据库优先)、Model-First(模型优先)、Code-First(代码优先)。其中前两种,数据库优先和模型优先是比较简单的两种模型。可以直接通过VS工具连接数据库自动生成与数据库交互的DbContext对象,这种模式有点像我们老早用过的不写一行代码就能自动绑定GridView一样(虽然有点夸张),虽然极大的提高了使用效率,但是灵活度欠缺。因此这篇博客,主要演示代码优先模型,所以起名为CodeFirstEF。

第二步,在CodeFirstEF中建立一个文件夹Entity,里面放置两个模型实体(学生和课程):

  1. namespace CodeFirstEF.Entity
  2. {
  3. public enum Gender { Female, Male }
  4.  
  5. public class Student
  6. {
  7. [Key]
  8. [DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
  9. public int StudentId { get; set; }
  10. public string StudentName { get; set; }
  11. public Gender Gender { get; set; }
  12. public DateTime? BirthDay { get; set; }
  13.  
  14. public virtual ICollection<Subject> Subjects { get; set; }
  15. }
  16. }

学生类上面有个枚举,用以区别性别。

  1. namespace CodeFirstEF.Entity
  2. {
  3. public class Subject
  4. {
  5. [Key]
  6. [DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
  7. public int SubjectId { get; set; }
  8. public string SubjectName { get; set; }
  9.  
  10. public virtual ICollection<Student> Students { get; set; }
  11. }
  12. }

课程和学生类中都有两个虚属性,分别表示学生的课程以及课程有哪些学生。

第三步,添加EntityFramework支持。

两个Entity建好了,下面关键的要添加对EF的引用,这里介绍一个强大的工具NuGet程序包。我们右键点击控制台项目CodeFirstEF,选择管理NuGet程序包,打开下列弹出界面,选择联机,找到EntityFramework。

选择安装EntityFramework。

下载好EntityFramework会弹出窗口。

选择我接受,很快就会装好,装好后如下所示。

点击关闭。这时我们已经为我们的项目添加了EntityFramework支持,可以看到版本号为6,这是目前的最新版本。

第四步,在CodeFirstEF控制台项目下建立一个文件夹DAL,并创建一个数据库操作类DataContext。

  1. namespace CodeFirstEF.DAL
  2. {
  3. public class DataContext : DbContext
  4. {
  5. public DataContext(string connectionName) : base(connectionName) { }
  6.  
  7. public DbSet<Student> Students { get; set; }
  8. public DbSet<Subject> Subjects { get; set; }
  9. }
  10. }

它继承自DbContext,需要引用命名空间 using System.Data.Entity。构造函数DbContext有一个参数connectionName,它是用于连接数据库的名称。这时我们切换到App.Config配置文件下,添加connectionStrings节点配置,将数据库连接的配置添加进去。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <configuration>
  3. <configSections>
  4. <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
  5. <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  6. </configSections>
  7. <connectionStrings>
  8. <add name="codeFirstDb" connectionString="Data Source=.;uid=sa;pwd=123456;Database=CodeFirstDb;" providerName="System.Data.SqlClient"/>
  9. </connectionStrings>
  10. <startup>
  11. <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  12. </startup>
  13. <entityFramework>
  14. <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  15. <providers>
  16. <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  17. </providers>
  18. </entityFramework>
  19. </configuration>

可以看到里面的codeFirstDb。

好了,这时候让我们看一下整个项目的结构。

第五步,在Program.cs的Main方法中写入测试代码。

  1. namespace CodeFirstEF
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. using (var db = new DataContext("codeFirstDb"))
  8. {
  9. //添加学生guwei4037
  10. if (!db.Students.Any(x => x.StudentName == "guwei4037"))
  11. {
  12. db.Students.Add(new Student()
  13. {
  14. StudentName = "guwei4037",
  15. Gender = Gender.Male,
  16. BirthDay = new DateTime(, , ),
  17. });
  18. }
  19.  
  20. //添加课程
  21. if (!db.Subjects.Any(x => x.SubjectName == "English" || x.SubjectName == "Mathmatics" || x.SubjectName == "Computer"))
  22. {
  23. db.Subjects.AddRange(new Subject[]
  24. {
  25. new Subject()
  26. {
  27. SubjectName="English",
  28. },
  29. new Subject()
  30. {
  31. SubjectName="Mathmatics",
  32. },
  33. new Subject()
  34. {
  35. SubjectName="Computer",
  36. }
  37. });
  38. }
  39.  
  40. //找到guwei4037这个学生
  41. Student student = db.Students.FirstOrDefault(x => x.StudentName == "guwei4037");
  42.  
  43. //找到数学和英语这两门课程
  44. List<Subject> subjects = db.Subjects.Where(x => x.SubjectName == "Mathmatics" || x.SubjectName == "English").ToList();
  45.  
  46. //给学生添加课程
  47. foreach (Subject subject in subjects)
  48. {
  49. student.Subjects.Add(subject);
  50. }
  51.  
  52. //让课程知道有哪些学生选择了它
  53. foreach (Subject subject in subjects)
  54. {
  55. subject.Students.Add(student);
  56. }
  57.  
  58. //删除guwei4037这个学生其中的数学这门课程
  59. student.Subjects.Remove(db.Subjects.FirstOrDefault(x => x.SubjectName == "Mathmatics"));
  60.  
  61. //保存上述操作的结果
  62. db.SaveChanges();
  63. }
  64. }
  65. }
  66. }

很简单,注释也很清晰。

运行一下整个控制台项目,没有报错说明程序运行成功了。我们进数据库查看一下运行的情况。

这里我们也可以利用VS工具来查看,无须打开SQL Server。

我们看到,EF替我们自动创建了数据库CodeFirstDb,并且为我们创建了一张中间表,而且将数据都插入到了相应表中。

怎么样,EF相当强大吧?而且非常简单好用,让你写代码有非常“爽”的感觉。真正的面向对象编程就是这么简单,不用再学习额外的SQL编程了。

Entity Framework多对多关联映射的实现的更多相关文章

  1. Entity Framework Many to Many Relation Mapping(Entity Framework多对多关系映射)

    通常我们在做数据库设计时都会有两张表是多对多关系的时候,在数据库做多对多关系时候我们通常通过中间关联表来处理,那我们现在在EF中是如何处理的呢? 假设我们有如下关系,用户(User)包含多个角色(Ro ...

  2. LINQ to SQL和Entity Framework对比与关联 (转载)

    LINQ to SQL和Entity Framework对比与关联       LINQ to SQL和Entity Framework都是一种包含LINQ功能的对象关系映射技术.他们之间的本质区别在 ...

  3. hibernate之关于使用连接表实现多对一关联映射

    [Hibernate]之关于使用连接表实现多对一关联映射 在我们项目使用中採用中间表最多的一般就是多对一,或者是多对多,当然一对一使用中间表也是能够的,可是这样的几率通常少之又少!所以这里重点介绍多对 ...

  4. 【SSH系列】Hibernate映射 -- 多对多关联映射

         映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论 ...

  5. Entity Framework Code First属性映射约定

    Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...

  6. (Hibernate进阶)Hibernate映射——多对多关联映射(八)

    多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数 ...

  7. Hibernate(六)——多对多关联映射

    前面几篇文章已经较讲解了三大种关联映射,多对多映射就非常简单了,不过出于对关联映射完整性的考虑,本文还是会简要介绍下多对多关联映射. 1.单向多对多关联映射 情景:一个用户可以有多个角色,比如数据录入 ...

  8. 017 多对多关联映射 双向(many-to-many)

    多对多关联映射 双向 两方都持有对象引用,修改对象模型,但数据的存储没有变化. 再修改映射文件: public class Role { private int id; private String ...

  9. 016 多对多关联映射 单向(many-to-many)

    一般的设计中,多对多关联映射,需要一个中间表 Hibernate会自动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联 多对多的关联映射,在实体类中,跟一对多一样,也是 ...

随机推荐

  1. ThinkPHP CURD方法盘点:order方法

    order方法属于模型的连贯操作方法之一,用于对操作的结果排序. 用法 $Model->where('status=1')->order('id desc')->limit(5)-& ...

  2. 用普通IO驱动LCD的控制方法-松瀚汇编源程序

    /*************************************** 本例程为IO直接驱动LCD的方法 以下是松瀚MCU汇编源程序 **************************** ...

  3. Funambol Developer&#39;s Guide 中 connector development样例的问题

    今天学习Funambol的connector开发,官方文档中的样例有问题. 首先,文档中提供的maven命令不可用: mvn archetype:generate -DarchetypeGroupId ...

  4. LVS DR模型

    1,环境 VMWare10, CentOS6.3 2,LVS DR网络规划 所有机器都只需要一张网卡,给Director的eth0网卡起个别名eth0:1即VIP的值:给RealServer的lo网卡 ...

  5. php递归无限极分类

    递归无限级分类有几种形式,我这里仅仅举例比較经常使用的三种: 第一种:返回有排序的数组: <?php $data = array( 1 => array( 'id' => 1, 'p ...

  6. iPad 3g版完美实现打电话功能(phoneitipad破解)

    看到这个标题,有的同学可能吐槽,iPad 用来打电话,多雷人啊,人家apple设计的时候没加电话功能是有益这样做的. 只是这次真的有这种需求,一台測试用的iPad 1 3G版的机器,放进去了一张3G电 ...

  7. 用linq实现登陆功能

    BLL层的逻辑代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; name ...

  8. C# 之 AES加密源码

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using Exam.Encr ...

  9. 【转】Git代码提交最佳实践

      GIT Commit Good Practice The following document is based on experience doing code development, bug ...

  10. 记一次大量 TCP 连接失败

    背景 在一段没有日志的历史遗留代码上面加入监控部署后不久,就收到了服务调用成功率低的告警,真是哗了狗了 解决过程 client端在线上单机部署,根据监控上面的返回码比例看出失败原因都是链接失败,通过 ...