分享

Entity Framework多对多关联映射的实现

 ThinkTank_引擎 2014-04-07

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(1984, 11, 25),  
  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编程了。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多