【译】第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中基于类的定义通过一 ...
随机推荐
- mysql的sql执行计划详解
实际项目开发中,由于我们不知道实际查询的时候数据库里发生了什么事情,数据库软件是怎样扫描表.怎样使用索引的,因此,我们能感知到的就只有 sql语句运行的时间,在数据规模不大时,查询是瞬间的,因此,在写 ...
- linux常用命令:cd 命令
Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的.所以,学习Linux 常用命令,首先就要学好 cd 命令的使用方法技巧. 1. 命 ...
- 20165215 2017-2018-2 《Java程序设计》第2周学习总结
20165215 2017-2018-2 <Java程序设计>第2周学习总结 教材学习内容总结 chapter2 逻辑类型boolea只能赋值true或false Java没有无符号整数类 ...
- 自学Java第二周的总结
在这一周里我在网上学习了java的对象和类,了解了对象与类以及简单的用法.对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种:行为有:摇尾巴. ...
- 前端框架VUE----计算属性和侦听器
一.计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div> {{ message.split('').rev ...
- 同行span标签设置display:inline-block;overflow:hidden垂直对齐问题
1 问题描述:一个div包含 三个span 当span2 类样式设置如下图时,将导致垂直方向不对齐的情况 2解决方案: 将前面的也设置同样的样式 overflow:hidden; display:in ...
- everything不显示移动硬盘中路径
点击他的设置选项,里面有NTFS,移除那些硬盘就可以了.
- 注册页面的JSON响应方式详细分析(与前端页面交互方式之一)
控制器层 需求分析: 访问路径:`/user/reg.do` //自己根据功能需求设定的请求参数:`username=xx&password=xx&&phone=xx& ...
- 合并ts到mp4
这个比较好用. copy /b d:\xxx\download_ts\* d:\xxx\download_ts\new.mp4 用python ffmpeg也可以,不过我合出来有卡顿或者掉声问题, ...
- Docker学习笔记之docker volume 容器卷的那些事(一)
预览目录 volume 方式 相关用例 使用方式 使用 volume driver bind mount 方式 相关用例 使用方式 配置selinux标签 配置macOS的安装一致性 tmpfs 方式 ...