【译】第5节---Code First约定
原文:http://www.entityframeworktutorial.net/code-first/code-first-conventions.aspx
我们在上一节中已经看到了EF Code-First如何从领域域类创建DB表。 在这里,我们将了解默认的Code-First约定。
什么是约定?
约定是一组默认规则,用于在使用Code-First时自动配置基于领域域类定义的概念模型。 Code-First约定在System.Data.Entity.ModelConfiguration.Conventions命名空间中定义。
让我们看看各种Code-First约定的概述。
类型发现
在上一节中,我们为想要成为模型的一部分的类创建了一个具有DbSet属性的上下文类。 Code-First将为包含为DbSet属性的类创建表,正如我们在上一节中所看到的那样。
Code-First还包括这些类中包含的任意引用类型,即使引用的类型在不同的程序集中定义。
例如,以下Student实体类包括Teacher类的引用。 但是,context类不包括Teacher作为DbSet属性。
public class Student
{
public Student()
{ }
public int StudentID { get; set; }
public string StudentName { get; set; }
public DateTime DateOfBirth { get; set; }
public byte[] Photo { get; set; }
public decimal Height { get; set; }
public float Weight { get; set; } public Teacher Teacher { get; set; } public Standard Standard { get; set; }
} public class Teacher
{
public Teacher()
{ }
public int TeacherId { get; set; }
public string TeacherName { get; set; }
}
以下是一个上下文类,不包括Teacher作为DbSet属性(实体集)
namespace EF_Code_First_Tutorials
{ public class SchoolContext: DbContext
{
public SchoolContext(): base()
{ } public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; } }
}
因此,即使Teacher不被包含在上下文类中的实体集中,Code-First将包含在概念模型中,并为其创建一个DB表,如下所示。
即使上下文类只包含基类作为DbSet属性,Code-First也包括派生类。
类型发现的约定是:
- Code-First包括在上下文类中定义为DbSet属性的类型。
- 代码首先包括实体类型中包含的引用类型,即使它们在不同的程序集中定义。
- Code-First包括派生类,即使只将基类定义为DbSet属性。
主键约定
在上一节中,我们已经看到Code-First在每个表中自动创建一个主键。
主键的默认约定是,如果属性名称为Id或<ClassName> Id(不区分大小写),则Code-First将为属性创建一个主键。
主键属性的数据类型可以是任何东西,但是如果主键属性的类型是数字或GUID,则它将被配置为标识列。
如果您定义了除Id或<ClassName> Id以外的键属性,那么将抛出ModelValidationException。 例如,考虑以下标准(Standard )类:
public class Standard
{
public Standard()
{ }
public int StdId { get; set; }
public string StandardName { get; set; }
public IList<Student> Students { get; set; }
}
像上面的代码中看到的那样,Standard类定义了StdId 键属性。 实体框架将抛出以下异常:
'System.Data.Entity.ModelConfiguration.ModelValidationException' occurred in EntityFramework.dll
EntityType 'Standard' has no key defined. Define the key for this EntityType.
如果要将StdId定义为主键,则必须使用DataAnnotations或Fluent API将其配置为主键。 我们将在后面的教程中看到如何做。
关系约定
Code-First使用导航属性推断两个实体之间的关系。导航属性可以是简单的引用类型或集合类型。
例如,我们在Standard类中定义了标准导航属性,并在Standard类中定义了ICollection <Student>导航属性。 因此,Code First通过在Students表中插入Standard_StandardId外键列,自动创建标准和学生DB表之间的一对多关系。
public class Student
{
public Student()
{ }
public int StudentID { get; set; }
public string StudentName { get; set; }
public DateTime DateOfBirth { get; set; }
public byte[] Photo { get; set; }
public decimal Height { get; set; }
public float Weight { get; set; } //Navigation property
public Standard Standard { get; set; }
} public class Standard
{
public Standard()
{ }
public int StandardId { get; set; }
public string StandardName { get; set; } //Collection navigation property
public IList<Student> Students { get; set; } }
上述实体使用Standard_StandardId外键创建了以下关系:
因此,关系的默认代码第一约定自动插入带有导航属性名称_导航属性类型的主键名称的外键。比如:Standard_StandardId。
外键约定
上面已经看到,当遇到导航属性时,Code First会自动插入一个外键。建议在关系的从属结尾附加一个外键属性。 请考虑以下示例:
public class Student
{
public Student()
{ }
public int StudentID { get; set; }
public string StudentName { get; set; }
public DateTime DateOfBirth { get; set; }
public byte[] Photo { get; set; }
public decimal Height { get; set; }
public float Weight { get; set; } //Foreign key for Standard
public int StandardId { get; set; } public Standard Standard { get; set; }
} public class Standard
{
public Standard()
{ }
public int StandardId { get; set; }
public string StandardName { get; set; } public IList<Student> Students { get; set; } }
在上面的代码中可以看到,Student类包括外键StandardId,它是Standard类中的key属性。
现在,Code First将在Students类中创建StandardId列,而不是Standard_StandardId列,如下所示:
请注意,在上图中,StandardId外键不为空。 这是因为int数据类型不可空。
Code First首先根据外键的可空性来推断关系的多样性。如果属性为空,那么该关系将被注册为null。 否则,该关系注册为NOT NULL。
将StudentId属性的数据类型从int修改为上面的Student类中的Nullable <int>,以在“学生”表中创建一个可空的外键列。
复杂类型约定
Code First为不包含key属性,并且还没有使用DataAnnotation或Fluent API注册主键的类创建复杂类型。
默认Code First约定
下面列出了Code First的默认约定:
1.表名:实体类名称+“s”
2.主键:id或类名+id(不区分大小写)
3.外键:默认情况下,EF将查找与主体实体主键名称相同名称的外键属性。如果不存在,则会创建外键为:导航属性_实体主键名称。(见上文示例)
4.可空列:所有引用类型和可空类型(nullable )
5.不可空列:主键和不可空列
6.数据库列顺序:按照实体类的顺序创建,主键会移动到第一个位置
7.属性映射到数据库:默认所有的属性都会映射到数据库,可以使用[NotMapped]特性进行排除
8.级联删除:所有关系类型默认开启
下表列出了C#数据类型映射到SQL数据类型,和主键列数据类型和长度:
C# DataType | Related DB Column DataType | PK Column DataType & Length |
---|---|---|
int | int | int, Identity column increment by 1 |
string | nvarchar(Max) | nvarchar(128) |
decimal | decimal(18,2) | decimal(18,2) |
float | real | real |
byte[] | varbinary(Max) | varbinary(128) |
datetime | datetime | datetime |
bool | bit | bit |
byte | tinyint | tinyint |
short | smallint | smallint |
long | bigint | bigint |
double | float | float |
char | No mapping | No mapping |
sbyte | No mapping (throws exception) |
No mapping |
object | No mapping | No mapping |
这是Code First约定的概述。
可以使用DataAnnotation或Fluent API覆盖这些约定。 此外,可以使用EF6.0+为应用程序定义自定义约定。
【译】第5节---Code First约定的更多相关文章
- Code First 约定
Code First 约定 借助 Code First,可通过使用 C# 或 Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code Fi ...
- Entity Framework 6新特性:全局性地自定义Code First约定
2012年12月11日,Entity Framework已经发布了Entity Framework 6 Alpha2,因项目需要,目前已使用了其中的两个特性,今天就来介绍一下第一个特性:全局性地自定义 ...
- EF6.0 自定义Code First约定
自定义Code First约定有三种方式,分别是:Lightweight Conventions(轻量级约定).Configuration Conventions(配置型约定).Model-based ...
- EntityFramWork(3 code First 约定)
Code First 约定 借助 Code First,可通过使用 C# 或 Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code ...
- EntityFramework Code-First 简易教程(二)-------Code First约定
Code First 约定 在前一篇中,我们已经知道了EF Code-First怎样从模型类(domain classes)中创建数据库表,下面,我们开始学习默认的Code-First约定. 什么是约 ...
- 【EF】Entity Framework 6新特性:全局性地自定义Code First约定
应用场景 场景一:EF Code First默认使用类名作为表名,如果我们需要给表名加个前缀,例如将类名Category映射到表Shop_Category.将Product映射到Shop_Produc ...
- Code First约定-数据注释
通过实体框架Code First,可以使用您自己的域类表示 EF 执行查询.更改跟踪和更新函数所依赖的模型.Code First 利用称为“约定先于配置”的编程模式.这就是说,Code First 将 ...
- 【译】第43节---EF6-自定义约定
原文:http://www.entityframeworktutorial.net/entityframework6/custom-conventions-codefirst.aspx Code-Fi ...
- Entity Framework Code First约定
Code First使你能够通过C# 或者 Visual Basic .NET来描述模型,模型的基本规则通过使用约定来进行检查,而约定就是一系列内置的规则. 在Code First中基于类的定义通过一 ...
随机推荐
- python range函数
这个函数很简单,就不写例子了,看看语法,拿来即用 python range() 函数可创建一个整数列表,一般用在 for 循环中. 函数语法 range(start, stop[, step]) 参数 ...
- LDA的Gibbs Sampling求解
<LDA数学八卦>对于LDA的Gibbs Sampling求解讲得很详细,在此不在重复在轮子,直接贴上该文这部分内容. Gibbs Sampling 批注: 1. ...
- 安装PG3.0详细教程附图
从公司要求开始着手调研PG到今天上午都还不知道如何安装PG.. 囧的离谱.. 看了半天的PG官网 就这个网页我瞅了半天..对你没看错 半天 少说有10分钟..原谅我的英文不是非常好..但是我知道什么意 ...
- CentOS7安装MySQL冲突和问题解决小结
摘自:https://blog.csdn.net/typa01_kk/article/details/49059729 问题1: [root@localhost install-files]# rpm ...
- mongoose与express
一.mongoose的使用1.先创建一个项目目录,初始化:npm init -y2.创建一个server.js文件,在该目录下安装mongoose:cnpm install mongoose3.引入m ...
- Python进阶【第八篇】迭代器和生成器
一.何谓迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration).迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代 ...
- python的一些遗漏用法
一. 补充基础数据类型的相关知识点 1. str. join() 把列表变成字符串 li = ["李嘉诚", "麻花藤", "⻩海峰", & ...
- OpenGL: 实现立体显示
https://blog.csdn.net/augusdi/article/details/19922295 立体显示原理:设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp,则.物 ...
- org.springframework.beans.factory.BeanCreationException,Invocation of init method failed,Context initialization failed
G:\javaanzhuang\apache-tomcat-\bin\catalina.bat run [-- ::,] Artifact ssm_qingmu02_web:war exploded: ...
- 斯坦福机器学习ex1.1(python)
使用的工具:NumPy和Matplotlib NumPy是全书最基础的Python编程库.除了提供一些高级的数学运算机制以外,还具备非常高效的向量和矩阵运算功能.这些对于机器学习的计算任务是尤为重要的 ...