MVC3+EF4.1学习系列(四)----- ORM关系的处理

时间:2020-12-13 09:30:27

上篇文章 终于把基础的一些操作写完了 但是这些都是单表的处理 而EF做为一个ORM框架  就必须点说说对于关系的处理

处理好关系 才能灵活的运用EF

关于关系的处理 一般就是  一对一   一对多  多对多  还有就是采用双向关联还是单项关联  而关系的处理  站长dudu的文章 就已经有了很好的介绍

推荐大家去看下 -------dudu的实体关系总结   这样大家对实体关系也就有了初步的认识了  但是在dudu的文章里 一直没有说如何处理多对多时 关系表

里有其他数据时怎么办(这个问题曾经困扰了我好久~~ 见人就问)  这里写下当时得到的几种方案 也希望能跟大家探讨下  好了 从实际项目开始 继续完善我们

的demo  并在从中探讨关系

先把原文中的完成后的图贴上来 也就是我们要处理的关系

MVC3+EF4.1学习系列(四)----- ORM关系的处理

这就是这次完成后样子    比以前多了几个类 关系也复杂了很多 下面我来解释这些关系

以及怎么建立的 一个一个慢慢来~~

一.创建教师实体

教师实体类

在第二篇文章里 简单的说了下用特性进行控制与MVC的结合 这里再详细的讲解几个

1.The Column Attribute

  [Column("FirstName")]
public string FirstMidName { get; set; }

利用这个特性 我们可以使FirstMidName属性映射到数据库的列为FirstName   在这里 如果使用[MaxLength(10)] 可以规定字段长度 [Required]这个来规定是否允许空 这是比较常用的

2. 请大家注意这个FullName

这个是不会被创建到数据库里的  因为它仅仅是获得 也就是一个get  这样是不会创建一个FullName列 在这个数据库表里的

3.普通的多对多的关系

这篇文章是这样  一个老师可以教多个课程  一个课程 也可以被多个老师教   与我们平时的习惯似乎有些不符合 但是尊重原文 这里依然这样设计  于是这就是一个多对多的关系

于是有了这个导航属性

public virtual ICollection<Course> Courses { get; set; }

4.一对一的关系

每个老师都要有一个办公位置  而一个办公位置 也只应该有一个老师  所以这是一个一对一的关系 用dudu的话 采用两情相悦的方式 双向关联  ps:这个类还没建呢~~

public virtual OfficeAssignment OfficeAssignment { get; set; }

二.创建办公地点实体

办公地点实体类

一对一的关系和KEY特效

继续刚才的一对一  因为一个老师只有一个办公地点 一个办公地点只有一个老师  所以 这张表希望和教师表一样  都用InstructorID做为主键 (就像有的时候 1对1的关系 我们放在一张表里一样) 而通过前面的学习 我们知道  EF寻找主键 的规则是 命名为ID 或者命名为 类名+ID   而这里面 没有符合要求的   遇到这种情况  我们可以通过[key] 来指定让谁做主键

[Key]
public int InstructorID { get; set; }

三.修改课程实体

课程实体

1.The DatabaseGenerated Attribute

用这个特性是关闭自增长   然后用主键当课程编号  创建时需要输入 其实这样做我并不赞同 但是这篇文章主要是讲EF 所以不纠结于细节 可能这里主要是为了讲解这个特性吧

有兴趣的可以看下原文~~

2.一对多的关系

因为一个院系可以开多个课程  一个课程只能属于一个院系 所以这里是一对多关系

在这个例子请注意 我们不仅拥有 院系的导航属性 还拥有一个导航属性ID

public int DepartmentID { get; set; }
public virtual Department Department { get; set; }

当你的命名是这种情况时 聪明的EF 是不会在数据库里给你建两个列的  如果你依然担心  可以使用 ForeignKey特效  来制定外键的名字

但是这里我有个疑问  我看到很多人的设计  都喜欢这样子做  既有导航属性  又有导航属性ID  这样做的意义是什么呢?方便获取 设置初始化值么?还是什么?我用EF时 不推荐这么用

四.创建院系类

一.The Column Attribute

[Column(TypeName="money")]
public decimal? Budget { get; set; }

通过这个特性 我们可以指定 生成到数据库里的列的属性

五.修改学生类

六.修改登记表(学生课程关系表)

修改登记表

七.多对多关系的思考与讨论

项目的类和关系建完了 这里我最想和大家探讨与分享的就是 这个如何处理多对多的关系

看我们的例子  其实有两个多对多  一个是课程和教师   还有一个是学生和选课

课程与教师 我们是直接使用多对多 没有为关系表建立实体类  因为我们的关系表不需要存储其他数据

而在学生和选课这里 要存储成绩  关系表里要存储其他的东西  这时 我们为关系表也建立了实体类  关系变成里  学生 1对多  关系表   课程也是1对多关系表

也就是说 当遇到使用多对多时 关系表还需要存储其他东西时(本文是成绩)  可以把多对多拆穿 两个1对多  还有 实际项目不建议使用多对多来处理关系

这是这个项目给的启事 请问大家是如何解决这种情况的呢? 所有的ORM都会遇到这种问题的吧?

这里 感谢下  桀骜的灵魂 和 dax.net

他们在领域驱动群里 给了我另一种解答 直接上图

MVC3+EF4.1学习系列(四)----- ORM关系的处理

晴天 15:23:04 
分数之间不需要区分个体,所以是值对象 
晴天 15:23:23 
学生和课程是需要系统维护的,所以是聚合根

晴天 15:25:13 
CourseMark保存针对Course的引用 
晴天 15:25:28 
Student下包含多个CourseMark

dax.net  关于双向关联

是不是双向关联不重要,首先要确定聚合根

班级是聚合根,学生也是聚合根  如果你的应用程序只是维护班级的基本信息,而不需要读取这个班级到底有哪些学生,那么就不需要往班级的聚合里添加学生

相反,通常情况下,学生的一个属性是班级,所以学生聚合里可以将班级加进去

八.关于EF的关系映射

看了这么多各种关系的类  他们之间存才的关系 多对多 一对一  一对多  处理这些映射是很麻烦的事

我们有三种方法  1.按EF默认的规则 自动生成  但是有时生成的不是我们想要的

2.通过特性的定义 来配置如何映射关系  以及如何映射到数据库  这篇文章提到了一些

3.通过流利的API 方式来定义   这也是我推荐的方式

看这篇文章的例子

MVC3+EF4.1学习系列(四)----- ORM关系的处理
using System;
using System.Collections.Generic;
using System.Data.Entity;
using ContosoUniversity.Models;
using System.Data.Entity.ModelConfiguration.Conventions; namespace ContosoUniversity.Models
{
public class SchoolContext : DbContext
{
public DbSet<Course> Courses { get; set; }
public DbSet<Department> Departments { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Instructor> Instructors { get; set; }
public DbSet<Student> Students { get; set; }
public DbSet<OfficeAssignment> OfficeAssignments { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Instructor>()
.HasOptional(p => p.OfficeAssignment).WithRequired(p => p.Instructor);
modelBuilder.Entity<Course>()
.HasMany(c => c.Instructors).WithMany(i => i.Courses)
.Map(t => t.MapLeftKey("CourseID")
.MapRightKey("InstructorID")
.ToTable("CourseInstructor"));
modelBuilder.Entity<Department>()
.HasOptional(x => x.Administrator);
}
}
}
MVC3+EF4.1学习系列(四)----- ORM关系的处理

依然很痛苦啊   这要多勇敢 才能把编写model 到再编写数据库映射等 写完  还有这么多api要记什么意思 实在是太痛苦了

不要怕 想用code fisrt  有干净的poco  但又不想写这些的  你们的福音来了  强烈推荐使用

Entity Framework Power Tools

可以根据数据库 一键生成想要的model 与映射    原子中也有介绍的了  介绍连接

生成后 和我们自己写的一样 而且更加规范 统一的映射管理 真的很完美~~

九.总结

通过这节 终于把ORM的关系理顺了 但是 这只是把关系建立起来   关系的处理远没结束

下一节   查找关联数据  如何利用好延迟加载与懒惰加载

MVC3+EF4.1学习系列(四)----- ORM关系的处理的更多相关文章

  1. MVC3&plus;EF4&period;1学习系列&lpar;五&rpar;----- EF查找导航属性的几种方式

    文章索引和简介 通过上一篇的学习 我们把demo的各种关系终于搭建里起来 以及处理好了如何映射到数据库等问题 但是 只是搭建好了关系 问题还远没有解决 这篇就来写如何查找导航属性 和查找导航属性的几种 ...

  2. MVC3&plus;EF4&period;1学习系列&lpar;十一&rpar;----EF4&period;1常见的问题解决

    博客写了10篇了~有很多朋友私信问了一些问题,而且很多问题 大家问的都一样 这里说说这些常见问题的解决办法.如果大家有更好的解决办法~也希望分享出来 问题大概为这几个 一.ef4.1 codeFirs ...

  3. MVC3&plus;EF4&period;1学习系列&lpar;三&rpar;-----排序 刷选 以及分页

    上篇文章 已经做出了基本的增删改查    但这远远不足以应付实际的项目  今天讲下实际项目中 肯定会有的 排序 刷选  以及分页. 重点想多写点分页的 毕竟这个是任何时候都要有的 而且 我会尽量把这个 ...

  4. MVC3&plus;EF4&period;1学习系列&lpar;一&rpar;-------创建EF4&period;1 code first的第一个实例

    基于EF4.1 code first 简单的CRUD  园子中已经有很多了 ~~ 真不想再写这个了 可是为了做一个完整的小demo 从开始 到后面的一些简单重构 还是决定认真把这个写出来 争取写些别人 ...

  5. MVC3&plus;EF4&period;1学习系列&lpar;二&rpar;-------基础的增删改查和持久对象的生命周期变化

    上篇文章中 我们已经创建了EF4.1基于code first的例子  有了数据库 并初始化了一些数据  今天这里写基础的增删改查和持久对象的生命周期变化 学习下原文先把运行好的原图贴来上~~ 一.创建 ...

  6. MVC3&plus;EF4&period;1学习系列&lpar;九&rpar;-----EF4&period;1其他的一些技巧的使用

    上节通过一系列重构 简单的项目就实现了 不过还有些EF的功能没有讲 这节就通过项目 讲讲EF其他的功能与技巧 一.直接执行SQL语句 通常来讲 EF 不用写SQL语句的  但是 在有些场合  比如对生 ...

  7. MVC3&plus;EF4&period;1学习系列&lpar;十&rpar;----MVC&plus;EF处理树形结构

    通过前几篇文章 我们处理了 一对一, 一对多,多对多关系 很好的发挥了ORM框架的做用 但是 少说了一种 树形结构的处理, 而这种树形关系 我们也经常遇到,常见的N级类别的处理, 以及经常有数据与类别 ...

  8. MVC3&plus;EF4&period;1学习系列&lpar;八&rpar;-----利用Repository and Unit of Work重构项目

    项目最基础的东西已经结束了,但是现在我们的项目还不健全  不利于测试 重复性代码多   层与层之间耦合性高  不利于扩展等问题.今天的这章 主要就是解决这些问题的.再解决这些问题时,自己也产生了很多疑 ...

  9. MVC3&plus;EF4&period;1学习系列&lpar;六&rpar;-----导航属性数据更新的处理

    通过上一篇的学习 我们已经知道怎么查询关系 这篇就来说说怎么导航属性数据更新时的处理 以及EF又会为我们生成哪些SQL~ 老规矩 先看下今天的图 添加和修改页面基本就是这样 这节的内容相对简单~~ 主 ...

随机推荐

  1. ubuntu执行sudo apt-get update提示缺少公钥

    提示信息如下: 获取:1 http://archive.ubuntukylin.com:10006/ubuntukylin xenial InRelease [3,192 B] 命中:2 http:/ ...

  2. 解决 Android SDK下载和更新失败&OpenCurlyDoubleQuote;Connection to https&colon;&sol;&sol;dl-ssl&period;google&period;com refused&period;&quot&semi;

    缘由: 更新sdk,遇到了更新下载失败问题: Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xml Fetch ...

  3. iOS8中如何将状态栏的字体颜色改为白色

    网上的一些方法在我这行不通, 比如: UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent ...

  4. linux如何安装MyEclipse 2014

    http://jingyan.baidu.com/article/0320e2c1cced031b87507b08.html

  5. MySQL在Linux系统下配置文件详解

    在日常的的开发过程中接触到了SQLServer和MySQL数据库的操作性问题,可能是以前接触的都是SQL Server,才开始接触MySQL,总感觉使用MySQL没有使用SQLserver那么顺手,一 ...

  6. QtSoap开发web services客户端程序

        首先需要下载QtSoap开源包,下载地址为: http://www.filestube.com/q/qtsoap+download, 我使用的是:qtsoap-2.6-opensource(不 ...

  7. oracle看到用户的所有表名、表睐、字段名称、现场的目光、是空的、字段类型

    --oracle看到用户的所有表名.表睐.字段名称.现场的目光.是空的.字段类型 select distinct TABLE_COLUMN.*, TABLE_NALLABLE.DATA_TYPE, T ...

  8. 【Luogu4781】【模板】拉格朗日插值

    [Luogu4781][模板]拉格朗日插值 题面 洛谷 题解 套个公式就好 #include<cstdio> #define ll long long #define MOD 998244 ...

  9. Nginx 入门指南

    Nginx 入门指南 简介: Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,其特点是占有内存少,并发能力强.本教程根据淘宝核心系统服务器平台组的 ...

  10. 转:Entity FrameWork利用Database&period;SqlQuery&lt&semi;T&gt&semi;执行存储过程并返回参数

    public IEnumerable<Statistic> GetStatistics(IEnumerable<Guid> itemIds) { var ctx = new D ...