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

简介:

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

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

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

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


第三步,添加EntityFramework支持。

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

Center

选择安装EntityFramework。

Center

下载好EntityFramework会弹出窗口。

Center

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

Center

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

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

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

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

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

可以看到里面的codeFirstDb。


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

Center

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

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

很简单,注释也很清晰。


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

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

Center

Center

Center

Center

Center

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

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



本文转自 guwei4037  51CTO博客,原文链接:http://blog.51cto.com/csharper/1356249


相关文章
|
4月前
|
机器学习/深度学习 SQL Java
Hibernate - 多对多关联关系映射
Hibernate - 多对多关联关系映射
35 0
|
SQL XML Java
MyBatis——关于一对多(<collection>)& 多对一(<association>)的案例详解
MyBatis——关于一对多(<collection>)& 多对一(<association>)的案例详解
MyBatis——关于一对多(<collection>)& 多对一(<association>)的案例详解
|
数据库
Entity Framework 一对多关系映射
Entity Framework 一对多关系映射
94 0
Entity Framework 一对多关系映射
|
存储 数据库
Entity Framework 多对多映射
Entity Framework 多对多映射
125 0
Entity Framework 多对多映射
|
SQL C# 数据库
Entity Framework 继承映射
Entity Framework 继承映射
115 0
Entity Framework 继承映射
|
Java 关系型数据库 数据库连接
Hibernate-ORM:12.Hibernate中的多对多关联关系
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------       本篇博客将讲述Hibernate中的多对多关联关系的操作,准备的篇幅较少,望海涵   一,讲述多对多   多对多的关联关系,比如学生和教师来说,一个学生由多个教师授课...
1243 0
|
Java 数据库连接
【Jpa hibernate】一对多@OneToMany,多对一@ManyToOne的使用
项目中使用实体之间存在一对多@OneToMany,多对一@ManyToOne的映射关系,怎么设置呢? GitHub地址:https://github.com/AngelSXD/myagenorderdiscount可以查看完整项目 下面给一个例子: 类似于一个部门对应多个员工 这里给出 一个流水账单对应多条订单折扣信息   流水账单类: package com.
8825 0
|
Java 关系型数据库 数据库连接