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
|
using System.ComponentModel.DataAnnotations.Schema; |
为类配置对应表名:
|
1
2
|
[Table("Product")]public class Product |
为类配置对应表名并指定表的所有者:
|
1
2
|
[Table("Product", Schema = "dbo")]public class Product |
2>、Fluent API方式
Fluent API实现配置Entity Framework Code First与数据库映射关系主要是通过继承DbContext并重写其中的OnModelCreating方法来进行的。在本文中新建类文件PortalContext.cs继承DbContext。
在继承DbContext之前,添加命名空间引用。
|
1
|
using System.Data.Entity; |
重写OnModelCreating方法,配置类对应于数据库中的表名:
|
1
2
3
4
|
protected override void OnModelCreating(DbModelBuilder modelBuilder){ modelBuilder.Entity<Product>().ToTable("Product");} |
重写OnModelCreating方法,配置类对应于数据库中的表名,并指定表的所有者:
|
1
2
3
4
|
protected override void OnModelCreating(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
|
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data.Entity;using Portal.Entities;namespace Portal{ public class PortalContext : DbContext { static PortalContext() { Database.SetInitializer(new DropCreateDatabaseIfModelChanges<PortalContext>()); } public PortalContext() : base("name=PortalContext") { } public DbSet<Product> Products { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Product>().ToTable("Product", "dbo"); } }} |
2、字段名、长度、数据类型及是否可空
在默认约定的情况下,Entity Framework Code First创建的列名与类的属性名相同,可以根据需要进行重新指定类属性与列名之间的映射关系。
1>、Data Annotation方式
|
1
2
3
4
5
|
[Column("ProductID")]public int ProductID { get; set; }[MaxLength(100)][Required, Column("ProductName")]public string ProductName { get; set; } |
在使用Required特性(Attribute)设置字段不允许为空时,需要添加命名空间引用:
|
1
|
using System.ComponentModel.DataAnnotations; |
2>、Fluent API方式
|
1
2
3
4
5
6
7
8
9
|
protected override void OnModelCreating(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")]public decimal UnitPrice { 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
|
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;namespace Portal.Entities{ [Table("Product", Schema = "dbo")] public class Product { [Column("ProductID")] public int ProductID { get; set; } [MaxLength(100)] [Required, Column("ProductName")] public string ProductName { get; set; } [Column("UnitPrice", TypeName = "MONEY")] public decimal UnitPrice { 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")]public int ProductID { get; set; } |
2>、Fluent API方式
|
1
2
3
4
|
protected override void OnModelCreating(DbModelBuilder modelBuilder){ modelBuilder.Entity<Product>().HasKey(t => t.ProductID);} |
若一个表有多个主键时:
|
1
2
3
4
|
protected override void OnModelCreating(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)]public int ProductID { get; set; } |
2>、Fluent API方式
|
1
2
3
4
5
6
7
|
protected override void OnModelCreating(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
|
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel.DataAnnotations.Schema;using System.Data.Entity.ModelConfiguration;using Portal.Entities;namespace Portal.Mapping{ public class ProductMap : EntityTypeConfiguration<Product> { public ProductMap() { // 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
|
protected override void OnModelCreating(DbModelBuilder modelBuilder){ modelBuilder.Configurations.Add(new ProductMap());}
|
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 ...
随机推荐
- Egret Engine 2D - 显示容器
DisplayObjectContainer 所有容器的父类 1 添加 删除 子对象 2 访问子对象 3 检测子对象 4 设置叠放次序 Sprite 继承自DisplayObjectContain ...
- 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 ...
- [RoarCTF 2019]Simple Upload
0x00 知识点 1:Think PHP上传默认路径 默认上传路径是/home/index/upload 2:Think PHP upload()多文件上传 think PHP里的upload()函数 ...
- POJ 1149:PIGS 网络流经典题
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18345 Accepted: 8354 Description ...
- python py pyc pyw pyo pyd之间区别
来源: http://blog.csdn.net/chroming/article/details/52083387 1.py 脚本文件,是最基本的源码扩展名.windows下直接双击运行会调用pyt ...
- CNN:卷积输出分辨率计算
卷积是CNN非常核心的操作,CNN主要就是通过卷积来实现特征提取的,在卷积操作的计算中会设计到几个概念:步长(strides).补充(padding).卷积核(kernel)等,那卷积的输出分辨率计算 ...
- SpringCloud----服务注册中心Eureka
Eureka是Netflix开源的一个RESTful服务,主要用于服务的注册发现.Eureka由两个组件组成:Eureka服务器和Eureka客户端.Eureka服务器用作服务注册服务器.Eureka ...
- JavaScript 之 异步请求
一. 1.异步(async) 异步,它的孪生兄弟--同步(Synchronous),"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排 ...
- ADFS 4.0 证书更新
ADFS 4.0 证书更新 由于公网证书的过期,需要重新更新ADFS的服务通信证书: 证书要求: 带私钥 PFX格式 更换流程: 证书安装到 证书\计算机\个人,安装后点开证书能看到"你有一 ...
- 题解 P1019 【单词接龙】
题目 单词具体是什么不重要,知道单词间如何转化即可 [分析] 先理清一下题意: \(n\)个单词,每个单词限用两次 上一个单词能与下一个单词接上,当且仅当上一个单词的末尾 \(k\) 个字符与下一个单 ...