原文: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也包括派生类。

类型发现的约定是:

  1. Code-First包括在上下文类中定义为DbSet属性的类型。
  2. 代码首先包括实体类型中包含的引用类型,即使它们在不同的程序集中定义。
  3. 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约定的更多相关文章

  1. Code First 约定

    Code First 约定 借助 Code First,可通过使用 C# 或 Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code Fi ...

  2. Entity Framework 6新特性:全局性地自定义Code First约定

    2012年12月11日,Entity Framework已经发布了Entity Framework 6 Alpha2,因项目需要,目前已使用了其中的两个特性,今天就来介绍一下第一个特性:全局性地自定义 ...

  3. EF6.0 自定义Code First约定

    自定义Code First约定有三种方式,分别是:Lightweight Conventions(轻量级约定).Configuration Conventions(配置型约定).Model-based ...

  4. EntityFramWork(3 code First 约定)

      Code First 约定 借助 Code First,可通过使用 C# 或 Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code ...

  5. EntityFramework Code-First 简易教程(二)-------Code First约定

    Code First 约定 在前一篇中,我们已经知道了EF Code-First怎样从模型类(domain classes)中创建数据库表,下面,我们开始学习默认的Code-First约定. 什么是约 ...

  6. 【EF】Entity Framework 6新特性:全局性地自定义Code First约定

    应用场景 场景一:EF Code First默认使用类名作为表名,如果我们需要给表名加个前缀,例如将类名Category映射到表Shop_Category.将Product映射到Shop_Produc ...

  7. Code First约定-数据注释

    通过实体框架Code First,可以使用您自己的域类表示 EF 执行查询.更改跟踪和更新函数所依赖的模型.Code First 利用称为“约定先于配置”的编程模式.这就是说,Code First 将 ...

  8. 【译】第43节---EF6-自定义约定

    原文:http://www.entityframeworktutorial.net/entityframework6/custom-conventions-codefirst.aspx Code-Fi ...

  9. Entity Framework Code First约定

    Code First使你能够通过C# 或者 Visual Basic .NET来描述模型,模型的基本规则通过使用约定来进行检查,而约定就是一系列内置的规则. 在Code First中基于类的定义通过一 ...

随机推荐

  1. 设计模式之Decorator(油漆工)(转)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

  2. JVM探秘3---垃圾回收机制详解

    众所周知,Java有自己的垃圾回收机制,它可以有效的释放系统资源,提高系统的运行效率.那么它是怎么运行的呢,这次就来详细解析下Java的垃圾回收 1.什么是垃圾? 垃圾回收回收的自然是垃圾,那么jav ...

  3. win10 校园宽带连接不上的解决办法(错误720、“以太网”没有有效的ip设置)

    遇到的问题如下图所示: 插上宽带后,查看以太网状态显示如下: 创建新连接宽带(PPPoE)(R)后,连接失败,错误为720,显示如下: 以太网网络诊断后,结果显示“以太网”没有有效的Ip设置,如下图所 ...

  4. Centos7 在apache+php7环境下 安装 Discuz!X3.4

    拉取Discuz!X3.4代码 git 地址 : https://gitee.com/ComsenzDiscuz/DiscuzX 在/var/www/html 中新建 bbs 文件夹 将git下upl ...

  5. Python进阶【第六篇】内置函数中好玩的几个(今天写的太水)

    zip()函数 两个参数一一对应,参数是序列类型,序列包括列表,元组,字符串,当两个序列不等长时,按公共最长部分匹配,形似“拉链”. max()和min()函数 以max()为例,min()类似,只是 ...

  6. python字符格式化

    使用%格式化字符串 字符串格式化使用格式化操作符即百分号. 在%号的左侧放置一个字符串(格式化字符串),而右侧则放置希望格式化的值. In [17]: name = "wxz" I ...

  7. Linux Redhat 安装免费yum源

    Linux Redhat 安装免费yum源 出处地址:http://www.cnblogs.com/nbartchen/p/8565816.html 1.查看是否安装相关包 rpm -qa|grep ...

  8. 《2015 html5 iweb 峰会观会后感》

    今天是2015  html5 iweb 峰会,大会在早上8:30,就开始了,没想到被坑了,看错一个字,把"国际会议中心",看成了"国家会议中心".大约过了10多 ...

  9. 细谈 Web Api 图片上传,在使用 Task.ContinueWith 变量无法赋值问题的解决办法!

    在使用Asp.Net Web Api 图片上传接口的时候,到网上找了一些个例子,但大多数找到都是这个版本! [HttpPost] public Task<Hashtable> ImgUpl ...

  10. CRC、MD5和SHA1的区别?

    什么是CRC校验?CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将 ...