第十四节: EF的三种模式(四) 之 原生正宗的 CodeFirst模式的默认约定
一. 简介
1. 正宗的CodeFirst模式是不含有edmx模型,需要手动创建实体、创建EF上下文,然后生成通过代码来自动映射生成数据库。
2. 旨在:忘记SQL、忘记数据库。
3. 三类配置:One To One(one-to-zero-or-one)、One To Many、Many To Many。
注意:在该模块使用最简单的模式配置这三种关系,暂时先不考虑DataAnnotation和Fluent API
A. One To One(one-to-zero-or-one)
①:一个学生对应一个或零个地址,一个地址只能对应一个学生
②:实现方式:
a:Student表中添加StudentAddress属性,StudentAddress表中添加Student属性,然后给StudentAddress中的主键加上[ForeignKey("stu")] ,
特别注意stu代表Student属性的名字。
b:编写配置文件
发现的现象
a.已经生成了一次数据库,修改表结构,会报错:数据添加失败支持“dbContext1”上下文的模型已在数据库创建后发生更改。
请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。
b. 类名+Id结尾属性自动生成主键。
c.生成的数据库默认保存在数据库的安装目录下。
d.在数据库中:StudentAddress中的studentAddressId既是主键,又是外键
B. One To Many
①:一个年级有多个学生,一个学生只能在一个年级
②:实现方式:
a:Student2表中添加Grade1属性,Grade1表中添加ICollection<Student2>属性
b:编写配置文件
发现的现象:
a. 数据库中:Student2表中,增加了一个新的字段grade1_grade1Id作为外键
C. Many To Many
①:一个学生有多门课,一门课有多个学生上
②:实现方式:
a:Student3表中添加ICollection<Course1>属性,Course1表中添加ICollection<Student3>属性
b:编写配置文件
发现的现象
a. 数据库中多了一张表:Student3Course1,里面有两个外键
二. 代码实战
1. One To One(one-to-zero-or-one)
/// <summary>
/// 学生表(一个学生只能有一个地址或没有地址)
/// </summary>
public class Student
{
public Student()
{ }
public string studentId { get; set; } public string studentName { get; set; } public virtual StudentAddress StudentAddress { get; set; }
}
/// <summary>
/// 学生地址表(一个地址只能对应一个学生)
/// </summary>
public class StudentAddress
{
public StudentAddress()
{ } [ForeignKey("stu")]
//特别注意这个地方,stu对应下面的 Student stu;
//另外特别注意:studentAddressId,符合默认的Id生成规则,自动映射成主键,否则需要加【key】特性
public string studentAddressId { get; set; } public string addressName { get; set; } public virtual Student stu { get; set; }
}
public class dbContext1:DbContext
{
public dbContext1()
: base("name=dbContext1")
{ }
public DbSet<Student> Student { get; set; } public DbSet<StudentAddress> StudentAddress { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
<!--正宗的CodeFirst OneToOne-->
<add name="dbContext1" connectionString="data source=localhost;initial catalog=CodeFirstDB1;persist security info=True;user id=sa;password=123456;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
2. One To Many
/// <summary>
/// 年级表(一个年级有多个学生)
/// </summary>
public class Grade1
{
public string grade1Id { get; set; } public string gradeName { get; set; } public virtual ICollection<Student2> student2 { get; set; }
}
/// <summary>
/// 学生表(一个学生只能在一个年级)
/// </summary>
public class Student2
{
public string student2Id { get; set; } public string studentName { get; set; } public virtual Grade1 grade1 { get; set; } }
public class dbContext2 : DbContext
{
public dbContext2()
: base("name=dbContext2")
{ }
public DbSet<Student2> Student2 { get; set; } public DbSet<Grade1> Grade1 { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
<!--正宗的CodeFirst OneToMany-->
<add name="dbContext2" connectionString="data source=localhost;initial catalog=CodeFirstDB2;persist security info=True;user id=sa;password=123456;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
3. Many To Many
/// <summary>
/// 学生表(一个学生有多门课)
/// </summary>
public class Student3
{
public string student3Id { get; set; } public string studentName { get; set; } public virtual ICollection<Course1> course { get; set; }
}
/// <summary>
/// 课程表(一门课会有多个学生上)
/// </summary>
public class Course1
{
public string course1Id { get; set; } public string courseName { get; set; } public virtual ICollection<Student3> student { get; set; }
}
public class dbContext3 : DbContext
{
public dbContext3()
: base("name=dbContext3")
{ }
public DbSet<Student3> Student3 { get; set; } public DbSet<Course1> Course1 { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
<!--正宗的CodeFirst OneToMany-->
<add name="dbContext3" connectionString="data source=localhost;initial catalog=CodeFirstDB3;persist security info=True;user id=sa;password=123456;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
三. 总结
上面的三种数据库表的对应关系主要都是采用的EF的默认协定,比如:
A: 类名+ID、类名+Id、类名+id自动生成主键(类名忽略大小写),
B: string类型自动映射成nvarchar(max)
但在实际开发中,默认协定显然不灵活,那么我们如何自定义配置呢(自定义主键、设置非空、设置类型、长度等),EF提供两种方式:DataAnnotations和Fluent API,但大多数情况都是两者配合使用,关于二者的详细使用,请见后面章节。
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
第十四节: EF的三种模式(四) 之 原生正宗的 CodeFirst模式的默认约定的更多相关文章
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- 第十节: EF的三种追踪实体状态变化方式(DBEntityEntry、ChangeTracker、Local)
一. 简介 我们在前面章节介绍EF基本增删改的时候,曾说过EF的SaveChanges()方法,会一次性的将所有的实体的状态变化统一提交到数据库,那么你是否想过EF的实体会有哪些状态变化呢?什么原因会 ...
- 第七节: EF的三种事务的应用场景和各自注意的问题(SaveChanges、DBContextTransaction、TransactionScope)
一. 什么是事务 我们通俗的理解事务就是一系列操作要么全部成功.要么全部失败(不可能存在部分成功,部分失败的情况). 举一个事务在我们日常生活中的经典例子:两张银行卡(甲.乙),甲向乙转钱,整个过程需 ...
- 第十一节: EF的三种模式(一) 之 DBFirst模式(SQLServer和MySQL两套方案)
一. 简介 EF连接数据库有三种模式,分别是DBFirst.ModelFirst.CodeFirst,分别适用于不同的开发场景. 该章节,将主要介绍EF的DBFirst连接SQLServer数据库和M ...
- 第十三节: EF的三种模式(三) 之 来自数据库的CodeFirst模式
一. 简介 [来自数据库的Code First模式]实质上并不是CodeFirst模式,而是DBFirst模式的轻量级版本,在该模式中取消了edmx模型和T4模板,直接生成了EF上下文和相应的类,该模 ...
- 第十五节: EF的CodeFirst模式通过DataAnnotations修改默认协定
一. 简介 1. DataAnnotations说明:EF提供以特性的方式添加到 domain classes上,其中包括两类: A:System.ComponentModel.DataAnnota ...
- EF的三种模式
1.DateBase First(数据库优先) 2.Model First(模型优先) 3.Code First(代码优先) 当然,如果把Code First模式的两种具体方式独立出来,那就是四种了. ...
- 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法
一. 背景 上一个章节,介绍了EF调用两类SQL语句,主要是借助 ExecuteSqlCommand 和 SqlQuery 两个方法来完成,在本章节主要是复习几类存储过程的写法和对应的EF调用这几类 ...
- Entity Framework 5.0系列之EF概览-三种编程方式
概述 在开发面向数据的软件时我们常常为了解决业务问题实体.关系和逻辑构建模型而费尽心机,ORM的产生为我们提供了一种优雅的解决方案.ADO.NET Entity Framework是.NET开发中一种 ...
随机推荐
- SQLServer之视图简介
视图定义 视图是一个虚拟表,其内容由查询定义. 同表一样,视图包含一系列带有名称的列和行数据. 视图在数据库中并不是以数据值存储集形式存在,除非是索引视图. 行和列数据来自由定义视图的查询所引用的表, ...
- Python基础之迭代器和生成器
阅读目录 楔子 python中的for循环 可迭代协议 迭代器协议 为什么要有for循环 初识生成器 生成器函数 列表推导式和生成器表达式 本章小结 生成器相关的面试题 返回顶部 楔子 假如我现在有一 ...
- D. Concatenated Multiples(离线处理)
思路:直接离线处理出每个ai 的10倍, 100倍, 1000倍的mod k 后的数值的个数,使用map<int,int >ss[12]存储, ss[x][y]表示 (ai*10x)%k= ...
- Maven基础入门与核心知识
Apache Maven是一个软件项目管理和综合工具.基于项目对象模型(POM)的概念,Maven可以从一个中心资料片管理项目构建,报告和文件. Maven是一个项目管理和综合工具.Maven提供了开 ...
- 二十九、layui分页插件的使用
<div id="page1"></div> <script> //开启分页 var page = 1; function findstoreL ...
- C#while死循环时候cpu占用比例大
C#while死循环时候cpu占用比例大 原因:线程等不到释放,windows运行模式是抢占资源 解决方法:休眠一毫秒让垃圾回收可以进来回收资源 while (true) { Thread.Sleep ...
- 关于PHP自动捕捉处理错误和异常的尝试
之所以想着做错误和异常的自动处理是因为: 用的公司自己的框架写API,没有异常和错误相关功能, 而每次操作都进行try...catch,有点繁琐不说,感觉还很鸡肋,即使我catch到了,还是得写代码进 ...
- 使用Node.js搭建数据爬虫crawler
0. 通用爬虫框架包括: (1) 将爬取url加入队列,并获取指定url的前端资源(crawler爬虫框架主要使用Crawler类进行抓取网页) (2)解析前端资源,获取指定所需字段的值,即获取有价值 ...
- 解决SVN一直弹出登录问题,eclipse.tmatesoft.com
Windows->preferences->Igonored Resources Add Pattern.. .project .classpath .settings 添加这三个: 把C ...
- linux服务端日志中截取自己所需要的部分
近期开发一个图片处理的业务,涉及base64字符串解析的问题,为方便与友商间接口调试,日志中保存Base64.日,想想就肝儿疼,记录下来容易,取的时候难.为准确提取,配合两条命令即可. 1.获取日志所 ...