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

应用场景

场景一:EF Code First默认使用类名作为表名,如果我们需要给表名加个前缀,例如将类名Category映射到表Shop_Category、将Product映射到Shop_Product,在EF 6之前,只能一个一个地使用Data Annotation( [Table("Shop_Category")] )或者Fluent API(ToTable("Shop_Category") )一个一个地指定表名。在实体类数量比较多的情况下,工作量就比较大了。

场景二:EF Code First默认将String类型的属性映射为nvarchar(max),但是你可能想要将它映射为nvarchar(255),那么也可以全局性地自定义,而不需要在所有String类型的属性上面使用[MaxLength(255)]进行配置。

当然使用场景不只这两个,如改写主外键的映射规则等等。简而言之,Custom Code First Conventions使你能够改写Entity Framework模型与数据库之间默认的映射规则。

自定义Code First约定的方式

Code First的默认映射规则可以通过三种方式进行自定义,分别是:Lightweight Conventions(轻量级约定)、Configuration Conventions(配置型约定)、Model-based Conventions(基于模型的配置)。实现上的复杂度由Lightweight Conventions开始依次递增,当然,实现的自由度也依次增大。

 1 public class ProductContext : DbContext 2 { 3 static ProductContext() 4 { 5 Database.SetInitializer( 6 new DropCreateDatabaseIfModelChanges<ProductContext>()); 7 } 8 9 public DbSet<Product> Products { get; set; } 10 } 11 12 public class Product 13 { 14 public int ProductId { get; set; } 15 public string Name { get; set; } 16 public string? Description {get; set;} 17 }

在这个模型中,默认情况下,EF会生成以下的数据表结构:

表名:Product

字段名称
类型
是否可空

ProductId
int
主键

Name
nvarchar(max)

Description
nvarchar(max)

我们以添加表前缀为例,来说明自定义Code First约定的前两种方式。

Lightweight Conventions

重写ProductContext的OnModelCreating(DbModelBuilder modelBuilder)方法:

1 public class ProductContext : DbContext 2 { 3 protected override void OnModelCreating(DbModelBuilder modelBuilder) 4 { 5 modelBuilder.Entities().Configure(entity => entity.ToTable("Shop_" + entity.ClrType.Name)); 6 } 7 }

Lightweight Conventions是最简单的实现方式,大部分的全局配置需求都能够以这种方式来实现。

Configuration Conventions

实现IConfigurationConvention<Type, EntityTypeConfiguration>接口,然后重写ProductContext的OnModelCreating(DbModelBuilder modelBuilder)方法。

 1 public class DefaultTableConvention 2 : IConfigurationConvention<Type, EntityTypeConfiguration> 3 { 4 public void Apply( 5 Type type, 6 Func<EntityTypeConfiguration> configuration) 7 { 8 TableAttribute[] tableAttributes = (TableAttribute[])type.GetCustomAttributes(typeof(TableAttribute), false); 9 10 if (tableAttributes.Length == 0) 11 { 12 configuration().ToTable("Shop_" + type.Name); 13 } 14 } 15 } 16 17 public class ProductContext : DbContext 18 { 19 protected override void OnModelCreating(DbModelBuilder modelBuilder) 20 { 21 modelBuilder.Conventions.Add<DefaultTableConvention>(); 22 } 23 }

从上面的代码可以看到,Configuration Conventions的方式需要自行判断实体是否使用TableAttribute指定了表名,如果是,则不使用全局的配置。而Lightweight Conventions则默认优先使用TableAttribute指定的表名。可以看出,Configuration Conventions实现起来相对繁琐了一点,但是自由度也更高。

IConfigurationConvention接口有两个类型参数:TMemberInfo和TConfiguration。它们用来过滤你想自定义约定的模型元素。

第一个类型参数,TMemberInfo,可以是一下两个值:

  • Type(System)

  • PropertyInfo(System.Reflection)

第二个类型参数,TConfiguration,可以是一下任意一种。

  • ModelConfiguration (System.Data.Entity.ModelConfiguration.Configuration)

  • EntityTypeConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Types)

  • PropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties)

  • NavigationPropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation)

  • PrimitivePropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive)

    • DateTimePropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive)

    • DecimalPropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive)

    • LengthPropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive)

      • BinaryPropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive)

      • StringPropertyConfiguration (System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive)

注意,Type和PropertyConfiguration(以及它的子类)不能混用,否则Configuration Conventions将不会生效。

增加自定义的Data Annotation

利用Custom Code First Conventions,我们还可以扩展自己的Data Annotation。例如,增加一个EmailAttribute特性,然后在Lightweight Conventions或者Configuration Conventions中,判断属性是否应用了EmailAttribute特性;如果是,则将列名映射为“Email”,列类型映射为“nvarchar(255)”, 达到了[Column("Email")]和[MaxLength(255)]共同作用的效果。

更详细的信息,请参考http://msdn.microsoft.com/en-us/data/jj819164.aspx

Entity Framework 6新特性:全局性地自定义Code First约定相关推荐

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

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

  2. Entity Framework走马观花之把握全局

    Entity Framework走马观花 之 把握全局 ========================================= 这是一个系列文章 上一篇<Entity Framewo ...

  3. [转]Entity Framework走马观花之把握全局

    学习Entity Framework技术期间查阅的优秀文章,出于以后方便查阅的缘故,转载至Blog,可查阅原文:http://blog.csdn.net/bitfan/article/details/ ...

  4. 浅析Entity Framework Core中的并发处理

    前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core的并发处理方式. 1.常见的并发处 ...

  5. [转]Entity Framework 4.1 正式版发布

    [转]Entity Framework 4.1 正式版发布 Entity Framework 4.1 正式版发布 投递人 itwriter发布于 2011-04-12 21:52 在MIX 11前夕, ...

  6. MVC3学习第六章 排山倒海第二变----使用 Entity Framework Code-First 进行数据访问

    本章学习内容 1.Entity Framework 4.1介绍 2.Entity Framework Code-First 进行数据访问 3.利用EF实现用户的增加和列表功能 1.Entity Fra ...

  7. Android 1.5 -10.0 都有哪些新特性?

    点击上方"开发者技术前线",选择"星标" 13:21 在看 真爱 本文部分整理 公众号 终端研发部 作者:嘟嘟呢 https://blog.csdn.net/u ...

  8. Android 1.5到10.0 都有哪些新特性?

    文章转自:https://www.itcodemonkey.com/article/13183.html Android 1.5(Cupcake纸杯蛋糕): 智能虚拟键盘:使用widgets实现桌面个 ...

  9. Android 1.5 到 10.0 新特性

    Android 1.5(Cupcake纸杯蛋糕): 智能虚拟键盘:使用widgets实现桌面个性化:在线文件夹(Live Folder)快速浏览在线数据:视频录制和分享:图片上传: 更快的标准兼容浏览 ...

最新文章

  1. vmware克隆centos修改linux mac地址
  2. 组播路由协议基础——组播分发树
  3. 一些实用的DBA语句之二(慢慢更新)
  4. python入门学习的第三天
  5. pythonif语句的多分支使用_Python多分支if语句的使用
  6. mysql 吧库下的表名都加_MySQL 数据库名、表名、字段名大小写敏感记录
  7. TensorFlow2.0:数据统计
  8. 百度正用谷歌AlphaGo,解决一个比围棋更难的问题 | 300块GPU在燃烧
  9. Linux 命令(27)—— echo 命令
  10. java scanner类成员_Java Scanner类的使用示例
  11. 计算机管理里面的“服务”怎么删除?
  12. 手势估计- Hand Pose Estimation
  13. 使用iMovie和Keynote制作App Preview
  14. 如何让Jmeter压力测试减少压力机的资源消耗
  15. RK3368 Edp屏调试,利用EDID做兼容
  16. cif和cip的区别_CIF与CIP价的区别?CIP价怎么算的?...
  17. 给Div添加边框颜色
  18. oralce的clob类型数据操作
  19. 我不能注销,重新启动,关闭我的windows XP机器?
  20. 如何从 Trados双语文件 中获得 原文 的方法

热门文章

  1. 新增标签 html知识,互联网常识:html5有哪些新增标签
  2. C++socket编程(三):3.3 bind端口
  3. python unicodeencodeerror_Python发起请求提示UnicodeEncodeError错误代码解决方法
  4. javascript内存泄漏调试工具mac_Vuex3.1.1更新:支持jsDelivr,修复内存泄漏
  5. elementui组件_elementui 中 loading 组件源码解析(续)
  6. arduino和单片机c语言,Arduino和单片机的区别-与非网
  7. java stream groupingBy
  8. python threading.lock
  9. Web Audio API 入门1
  10. docker stop