【EF】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());} |
【EF】Entity Framework实现属性映射约定的更多相关文章
- 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 ...
- [转载]灵动思绪EF(Entity FrameWork)
很久之前就想写这篇文章了,但是由于种种原因,没有将自己学习的EF知识整理成一片文章.今天我就用CodeFirst和ModelFirst两种方式的简单案例将自己学习的EF知识做个总结. 在讲解EF之前, ...
- 第三篇: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 默认约定: 表名为类名的 ...
- EF(Entity Framework)多对多关系下用LINQ实现"NOT IN"查询
这是今天在实际开发中遇到的一个问题,需求是查询未分类的博文列表(未加入任何分类的博文),之前是通过存储过程实现的,今天用EF实现了,在这篇博文中记录一下. 博文的实体类BlogPost是这样定义的: ...
随机推荐
- 20155322 2017-2018-1《信息安全系统设计》第十周 课下作业-IPC
20155322 2017-2018-1<信息安全系统设计>课下作业-IPC 作业内容 研究Linux下IPC机制:原理,优缺点,每种机制至少给一个示例,提交研究博客的链接. 共享内存 管 ...
- 20155327 2016-2017-2 《Java程序设计》第一周学习总结
20155327 2016-2017-2 <Java程序设计>第一周学习总结 教材学习内容总结 浏览教材,根据自己的理解每章提出一个问题 1.JAVA SE中JVM,JRE与JDK分别是什 ...
- 20155338 2016-2017-2 《Java程序设计》第3周学习总结
20155338 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 本周学习量比较多,但是知识点并不是特别难,学习了书本的第四五章,其中个人重点学习了数组对象. ...
- JQuery事件机制
1 事件操作 1.1 页面载入事件 $(document).ready(function(){ // 在这里写你的代码... }); 或者 $(function($) { // 你可以在这里继续使用$ ...
- Linux 内核3.10.5 专场
今天本人十分靠谱地下载了linux 内核的3.10.5版本,这个版本是最新的稳定版. 听路飞大虾(哪个路飞?就是那个戴草帽的橡胶小伙,航海很多时候都很空闲的,于是最近他也开始研读linux 内核了.) ...
- ASP.NET获取汉字拼音的首字母
代码 #region GetChineseSpell获取汉字拼音的第一个字母 //获取汉字拼音的第一个字母 static public string GetChineseSpell(string st ...
- FTP如何通过Windows防火墙
将C:\Windows\SysWOW64\ftp.exe(64位系统)C:\Windows\system32\ftp.exe(32位系统)文件添加到防火墙的允许列表中即可. 注:“控制面板” -> ...
- ffmpeg 踩坑实录 近期使用总结(三)
一.背景介绍 将ffmpeg运用到项目上已经有一段时间了,趁现在有空赶紧记下来. 二.技术点总结 2.1 实现方式 项目里面主要运用的形式是,在java端,调用操作系统的方法,并执行切片命令. ...
- Jmeter使用JDBC链接数据库进行压力测试
一.关于性能测试 对数据库进行压测时,我们需要关注的几个方面: 1.系统相关指标,诸如:系统CPU/内存/IO等 2.进程相关指标,诸如:mysql该数据库的对应的进程占用CPU/内存/IO等 3.数 ...
- Python不生成HTMLTestRunner报告-转载学习
1.问题:Python中同一个.py文件中同时用unittest框架和HtmlReport框架后,HtmlReport不被执行. 2.为什么?其实不是HtmlReport不被执行,也不是HtmlRep ...