Entity Framework 6新特性:全局性地自定义Code First约定
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约定的更多相关文章
- 【EF】Entity Framework 6新特性:全局性地自定义Code First约定
应用场景 场景一:EF Code First默认使用类名作为表名,如果我们需要给表名加个前缀,例如将类名Category映射到表Shop_Category.将Product映射到Shop_Produc ...
- [转]Entity Framework走马观花之把握全局
本文转自:http://blog.csdn.net/bitfan/article/details/12887007 Entity Framework走马观花 之 把握全局 ============== ...
- 重新想象 Windows 8.1 Store Apps (92) - 其他新特性: CoreDispatcher, 日历, 自定义锁屏系列图片
[源码下载] 重新想象 Windows 8.1 Store Apps (92) - 其他新特性: CoreDispatcher, 日历, 自定义锁屏系列图片 作者:webabcd 介绍重新想象 Win ...
- Entity Framework 实体框架的形成之旅--Code First模式中使用 Fluent API 配置(6)
在前面的随笔<Entity Framework 实体框架的形成之旅--Code First的框架设计(5)>里介绍了基于Code First模式的实体框架的经验,这种方式自动处理出来的模式 ...
- Entity Framework 实体框架的形成之旅--Code First的框架设计(5)
在前面几篇介绍了Entity Framework 实体框架的形成过程,整体框架主要是基于Database First的方式构建,也就是利用EDMX文件的映射关系,构建表与表之间的关系,这种模式弹性好, ...
- EF6.0 自定义Code First约定
自定义Code First约定有三种方式,分别是:Lightweight Conventions(轻量级约定).Configuration Conventions(配置型约定).Model-based ...
- Entity Framework走马观花之把握全局 (转)
上一篇<Entity Framework技术导游系列开篇与热身 > ========================================= 在深入学习某项技术之前,应该努力形成 ...
- Entity Framework 6新功能Logging/Store Procedure
摘要 在Entity Framework6中有两个新的功能,DB Loggin和Stored Procedure的映射 Entity Framework 6已经从Beta版本来到了RC1版本,我们可以 ...
- C#10新特性-全局和隐式usings
.NET 6发布后支持C#10,C# 10 向 C# 语言添加了很多功能,今天我们分享一下全局和隐式usings的使用: using 指令简化了使用命名空间的方式. C# 10 包括一个新的全局 us ...
随机推荐
- python global vs nonlocal (2)
上一篇中简述了这两个关键字的基本用法: global用于在局部作用于修改或重定义全局变量 nonlocal用于在内部作用域修改或重定义外部变量(全局变量除外) 这只是很浅的理解方式 注意python的 ...
- python构建模拟模型——网站独立访问用户数量
背景:发现一个有趣的现象,即一些用户在每一月都仅仅访问网站一次,我们想要了解这些人数量的变化趋势. 建立数学模型:简化问题,根据瓮模型推导出公式(具体推导见<数据之魅>,有时间再补充... ...
- JQuery源码解析(九)
jQuery回调对象 jQuery.Callbacks一般开发者接触的很少,虽然jQuery向开发者提供了外部接口调用,但是$.Callbacks()模块的开发目的是为了给内部$.ajax() 和 $ ...
- HDU 5093
http://acm.hdu.edu.cn/showproblem.php?pid=5093 二分图最大匹配的经典建图模型,行列分别缩点(连起来的'*' & 'o'),交集有'*'就连边 #i ...
- sql2008+vs2008安装心得以及详细教程分享
第一步,我把原来装的vs2005+sql2005全部卸载了 第二步,下载VS2008同时下载sql2008: 第三步,开始安装VS2008专业版,网上有很多给出了微软的地址,在这里我也贴一个吧 htt ...
- 第二个Sprint冲刺第四天
讨论地点:宿舍 讨论成员:邵家文.李新.朱浩龙.陈俊金 今天的发展,探讨了统计功能的问题: 一.统计数据针对的是什么功能? 1.初衷是针对计时的填空题,至于其它功能统不统计,那要看开发的进度. 二.对 ...
- 关于cocos2d-x 与 cocos2d-html5 资源预加载的思考
移动端资源预加载,可以做到需要加载的时候,从本地磁盘加载到内存,当纹理不需要的时候,都是强制清理内存里的纹理占用: cc.TextureCache.getInstance().removeAllTex ...
- 听VOA还不如学这些 (转自知乎恶魔奶爸)
该专栏文章网址 http://zhuanlan.zhihu.com/aisapo/19634180 鉴于知乎无法插图片和音频,所以有了这篇教程集合,大家看这个就足够了其实 每次一学英语,材料无非就是V ...
- 【转】7 Tips to Speed Up Eclipse
技巧一:运行最新版本的JDK和Eclipse 通常,新版本的JDK和Eclipse都会有性能上的优化.请确保你使用的是64位Eclipse并且使用了Oracle的JDK.对于网络开发,需要使用Ecli ...
- UITextView 点return 隐藏键盘
iOS开发中,发现UITextView没有想UITextField中textFieldShouldReturn:这样的方法,那么要实现UITextView return键隐藏键盘,可以通过判断输入的字 ...