Entity Framework实现属性映射约定
Entity Framework Code First属性映射约定中“约定”一词,在原文版中为“Convention”,翻译成约定或许有些不好理解,这也是网上比较大多数的翻译,我们就当这是Entity Framework的一些使用“规则”,这样或许更好理解一些。
Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API。本文中采用创建Product类为例来说明tity Framework Code First属性映射约定的具体方式。
1、表名及所有者
在默认约定的情况下,Entity Framework Code First创建的表名是根据类名的英语复数形式,创建的表所有者为dbo,可以通过重写约定来指定表名及表的所有者。
1>、Data Annotation方式
在使用Data Annotation方式进行Entity Framework Code First与数据库映射之前,需要先添加命名空间引用。
| 1 | usingSystem.ComponentModel.DataAnnotations.Schema; | 
为类配置对应表名:
| 1 2 | [Table("Product")]publicclassProduct | 
为类配置对应表名并指定表的所有者:
| 1 2 | [Table("Product", Schema = "dbo")]publicclassProduct | 
2>、Fluent API方式
Fluent API实现配置Entity Framework Code First与数据库映射关系主要是通过继承DbContext并重写其中的OnModelCreating方法来进行的。在本文中新建类文件PortalContext.cs继承DbContext。
在继承DbContext之前,添加命名空间引用。
| 1 | usingSystem.Data.Entity; | 
重写OnModelCreating方法,配置类对应于数据库中的表名:
| 1 2 3 4 | protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity<Product>().ToTable("Product");} | 
重写OnModelCreating方法,配置类对应于数据库中的表名,并指定表的所有者:
| 1 2 3 4 | protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity<Product>().ToTable("Product", "dbo");} | 
到此处PortalContext.cs的完整代码:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Data.Entity;usingPortal.Entities;namespacePortal{    publicclassPortalContext : DbContext    {        staticPortalContext()        {            Database.SetInitializer(newDropCreateDatabaseIfModelChanges<PortalContext>());        }        publicPortalContext()            : base("name=PortalContext")        {        }        publicDbSet<Product> Products { get; set; }        protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder)        {            modelBuilder.Entity<Product>().ToTable("Product", "dbo");        }    }} | 
2、字段名、长度、数据类型及是否可空
在默认约定的情况下,Entity Framework Code First创建的列名与类的属性名相同,可以根据需要进行重新指定类属性与列名之间的映射关系。
1>、Data Annotation方式
| 1 2 3 4 5 | [Column("ProductID")]publicintProductID { get; set; }[MaxLength(100)][Required, Column("ProductName")]publicstringProductName { get; set; } | 
在使用Required特性(Attribute)设置字段不允许为空时,需要添加命名空间引用:
| 1 | usingSystem.ComponentModel.DataAnnotations; | 
2>、Fluent API方式
| 1 2 3 4 5 6 7 8 9 | protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity<Product>().Property(t => t.ProductID)        .HasColumnName("ProductID");    modelBuilder.Entity<Product>().Property(t => t.ProductName)        .IsRequired()        .HasColumnName("ProductName")     .HasMaxLength(100);} | 
在默认情况下,int类型的属性生成的列名对应SQL SERVER列int类型;而String类型的属性则对应SQL SERVER列的NVARCHAR类型。若类的字符串类型属性未设置MaxLength,则生成对应的列类型为NVARCHAR(MAX)。
为属性指定对应的SQL SERVER数据类型:
| 1 2 3 4 5 | [Column("UnitPrice", TypeName = "MONEY")]publicdecimalUnitPrice { get; set; }modelBuilder.Entity<Product>().Property(t => t.UnitPrice)    .HasColumnName("UnitPrice")    .HasColumnType("MONEY"); | 
到此步,Product.cs类文件的完整代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.ComponentModel.DataAnnotations;usingSystem.ComponentModel.DataAnnotations.Schema;namespacePortal.Entities{    [Table("Product", Schema = "dbo")]    publicclassProduct    {        [Column("ProductID")]        publicintProductID { get; set; }        [MaxLength(100)]        [Required, Column("ProductName")]        publicstringProductName { get; set; }        [Column("UnitPrice", TypeName = "MONEY")]        publicdecimalUnitPrice { get; set; }    }} | 
3、主键
Entity Framework Code First的默认主键约束:属性名为[ID]或[类名 + ID]。如在Product类中,Entity Framework Code First会根据默认约定将类中名称为ID或ProductID的属性设置为主键。Entity Framework Code First主键的默认约定也一样可以进行重写,重新根据需要进行设置。
1>、Data Annotation方式
| 1 2 3 | [Key][Column("ProductID")]publicintProductID { get; set; } | 
2>、Fluent API方式
| 1 2 3 4 | protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity<Product>().HasKey(t => t.ProductID);} | 
若一个表有多个主键时:
| 1 2 3 4 | protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity<Product>().HasKey(t => new{ t.KeyID, t.CandidateID });} | 
4、数据库自动生成字段值
Entity Framework Code First对于int类型的主键,会自动的设置其为自动增长列。但有时我们确实不需是自动增长的,可以通过以下方式进行取消自动增长。
1>、Data Annotation方式
| 1 2 3 4 | [Key][Column("ProductID")][DatabaseGenerated(DatabaseGeneratedOption.None)]publicintProductID { get; set; } | 
2>、Fluent API方式
| 1 2 3 4 5 6 7 | protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity<Product>().HasKey(t => t.ProductID);    modelBuilder.Entity<Product>().Property(t => t.ProductID)        .HasColumnName("ProductID")        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);} | 
5、数字类型长度及精度
在Product类中,UnitPrice表示单价,对于价格类的字段,我们通常会希望其保留2为小数。这时可以使用Fluent API进行设置,且Data Annotation不支持该设置。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>().Property(t => t.UnitPrice)
        .HasColumnName("UnitPrice")
        .HasPrecision(18, 2);
}
6、非数据库字段属性
在类中,如果有一些属性不需要映射到对应生成的数据表中,可以通过以下方式设置。
1>、Data Annotation方式
[NotMapped]
public string Remark { get; set; }
2>、Fluent API方式
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>().Ignore(t => t.Remark);
}
7、Fluent API配置Configuration映射类
在使用Fluent API进行Entity Framework Code First数据库映射时,除了以上的在重写OnModelCreating方法中直接对Entity进行配置之外,也可以对Configurations进行配置。这时可以先写一个单独的类,将数据表的全部映射要求都写在构造函数中。
ProductMap.cs类
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.ComponentModel.DataAnnotations.Schema;usingSystem.Data.Entity.ModelConfiguration;usingPortal.Entities;namespacePortal.Mapping{    publicclassProductMap : EntityTypeConfiguration<Product>    {        publicProductMap()        {            // Primary Key            this.HasKey(t => t.ProductID);            // Properties            this.Property(t => t.ProductID)                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);            this.Property(t => t.ProductName)                .IsRequired()                .HasMaxLength(100);            // Table & Column Mappings            this.ToTable("Product");            this.Property(t => t.ProductID).HasColumnName("ProductID");            this.Property(t => t.ProductName).HasColumnName("ProductName");            this.Property(t => t.UnitPrice)                .HasColumnName("UnitPrice")                .HasPrecision(18, 2);        }    }} | 
有了上面的映射类之后,在重写OnModelCreating方法中则可以直接调用映射类,从而减少了OnModelCreating方法的复杂度,同时也增强了代码维护的可读性。
| 1 2 3 4 | protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Configurations.Add(newProductMap());}
 | 
Entity Framework实现属性映射约定的更多相关文章
- 【EF】Entity Framework实现属性映射约定
		Entity Framework Code First属性映射约定中“约定”一词,在原文版中为“Convention”,翻译成约定或许有些不好理解,这也是网上比较大多数的翻译,我们就当这是Entity ... 
- Entity Framework Code First属性映射约定
		Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ... 
- 补习知识:Entity Framework Code First属性映射约定
		Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ... 
- Entity Framework Code First属性映射约定  转载https://www.cnblogs.com/libingql/p/3352058.html
		Entity Framework Code First属性映射约定 Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Flue ... 
- 第三篇:Entity Framework CodeFirst & Model 映射 续篇 EntityFramework Power Tools 工具使用
		上一篇 第二篇:Entity Framework CodeFirst & Model 映射 主要介绍以Fluent API来实作EntityFramework CodeFirst,得到了大家一 ... 
- 第二篇:Entity Framework CodeFirst & Model 映射
		前一篇 第一篇:Entity Framework 简介 我有讲到,ORM 最关键的 Mapping,也提到了最早实现Mapping的技术,就是 特性 + 反射,那Entity Framework 实现 ... 
- EFCodeFirst属性映射约定
		EFCodeFirst属性映射约定 EFCodeFirst 属性映射约定 CodeFirst与数据表之间得映射方式又两种:Data Annotation和Fluent API 默认约定: 表名为类名的 ... 
- Entity Framework Code First 映射继承关系
		转载 http://www.th7.cn/Program/net/201301/122153.shtml Code First如何处理类之间的继承关系.Entity Framework Code Fi ... 
- Programming Entity Framework CodeFirst--数据库约定和配置
		这一章主要主要讲的是我们的模型如何映射到数据库,而不影响模型,以及不同的映射场景. 一.表名和列名 1.指定表名 [Table("PersonPhotos")] public cl ... 
随机推荐
- 2 ~ express ~ 模板引擎的配置与使用
			一,创建应用 (一),创建应用,监听端口 var express = require('express') // 创建app应用 var app = express() app.listen(3000 ... 
- 关联容器--保存指针时要指定容器的比较类型---引用Effective STL
			无论何时你建立指针的关联容器,注意你也得指定容器的比较类型.大多数时候,你的比较类型只是解引用指针并比较所指向的对象(就像上面的StringPtrLess做的那样).鉴于这种情况,你手头最好也能有一个 ... 
- blkid命令 获取文件系统类型、UUID
			在Linux下可以使用blkid命令对查询设备上所采用文件系统类型进行查询.blkid主要用来对系统的块设备(包括交换分区)所使用的文件系统类型.LABEL.UUID等信息进行查询.要使用这个命令必须 ... 
- ABP框架没有httpPost,httpget,httpput特性
			需要引用一下组件, Microsoft.AspNetCore.Mvc 
- RecyclerView+FloatingActionButton应用
			一.效果图 二.实现步骤 1.XML布局-添加依赖 <LinearLayout android:id="@+id/layout" android:layout_width=& ... 
- MVC三层架构在各框架中的特征
			转一篇写得很棒的文章:https://my.oschina.net/win199176/blog/208171?p=7&temp=1495894148424 1.基于web开发中最原始的jsp ... 
- CSS3 之高级动画(6)CSS3 clip-path属性实现的几何图形变形动画
			clip-path 属性介绍: clip-path属性可以创建一个只有元素的部分区域可以显示的剪切区域. 区域内的部分显示,区域外的隐藏. 剪切区域是被引用内嵌的URL定义的路径或者外部svg的路径. ... 
- docker创建redis容器
			1.拉取最新的redis镜像 docker pull redis; 2.创建存放redis数据的目录 mkdir /redis/data 3.查询redis镜像id docker images; RE ... 
- E - Third-Party Software - 2 Gym - 102215E (贪心)
			Pavel is developing another game. To do that, he again needs functions available in a third-party li ... 
- mysql第四篇:数据操作之多表查询
			mysql第四篇:数据操作之多表查询 一.多表联合查询 #创建部门 CREATE TABLE IF NOT EXISTS dept ( did int not null auto_increment ... 
