Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表。然而,有时候,不能也不想遵循这些约定,那就需要重写它们。重写默认约定有两种方式:Data Annotations和FluentAPI。Data Annotations在功能上是Fluent API的子集,在一些映射场景下使用Annotations不能达到重写的目的,因此本篇文章中使用Fluent API配置属性。
一、Fluent API配置属性
Code First Fluent API通常情况下是在DbContext的派生类中重写OnModelCreating方法。
1.配置Length
Length用来描述数组的长度,当前包括string和Byte数组。
默认约定:Code First对string或byte数组的默认长度约定是max。注意:Sql Server Compact中默认最大数组长度是4000。
重写约定:使用HasMaxLength(nn),参数为可空整数。
1: Property(t => t.Name).HasMaxLength(50);
另外关于Length的Fluent API还有下面2个:
IsFixedLength(),配置属性为固定长度。
IsMaxLength(),配置属性为数据库提供程序允许的最大长度。
2.配置Data Type
Data Type表示将.NET类型映射到的数据库的数据类型。
默认约定:列的数据类型由使用的数据库提供程序决定。以SQL Server为例:String->nvarchar(max),Integer->int,Byte[]->varbinary(max),Boolean->bit。
重写约定:使用HasColumnType(“xxx”),下面列子的Photo是byte[]类型,配置映射到image数据类型:
1: Property(t => t.Photo).HasColumnType("image");
3.配置允许为空和不允许为空
默认约定:主键属性不允许为空,引用类型(String,array)允许为空,值类型(所有的数字类型,Datetime,bool,char)不允许为空,可空的值类型Nullable<T>允许为空。
重写约定:使用IsRequired()配置不允许为空,使用IsOptional()配置允许为空。下面配置Name属性为不为空:
1: Property(t => t.Name).IsRequired();
4.配置属性到指定列
默认约定:映射到与属性名相同的列。
重写约定:使用Property(t=>t.属性名).HasColumnName(“xxx”)。下面配置Name映射到DepartmentName:
1: Property(t => t.Name).HasColumnName("DepartmentName");
5.配置主键
默认约定:(1)属性名为ID或Id的默认为主键
(2)类名+ID或类名+Id默认为主键 (其中ID或Id的优先级大于类名+ID或类名+Id)
重写约定:使用HasKey(t=>t.属性名)。下面将BlogId配置为主键:
1: HasKey(t => t.BlogId);
6.配置组合主键
下面的例子将DepartmentId和Name属性组合作为Department类型的主键:
1: HasKey(t => new { t.DepartmentId, t.Name });
7.配置Database-Generated
默认约定:整型键:Identity。
重写约定:使用Property(t => t.属性名).HasDatabaseGeneratedOption(DatabaseGeneratedOption)。
DatabaseGeneratedOption枚举包括三个成员:
(1) None:数据库不生成值
(2) Identity:当插入行时,数据库生成值
(3) Computed:当插入或更新行时,数据库生成值
整型默认是Identity,数据库生成值,自动增长,如果不想数据库自动生成值,使用DatabaseGeneratedOption.None。
Guid类型作为主键时,要显示配置为DatabaseGeneratedOption.Identity。
8.配置TimeStamp/RowVersion的乐观并发
默认约定:这个没有默认约定。
配 置:使用Property(t=>t.属性名).IsRowVersion()
1: Property(t => t.RowVersion).IsRowVersion();
9.不配置TimeStamp的乐观并发
有些数据库不支持RowVersion类型,但是又想对数据库的一个或多个字段并发检查,这时可以使用Property(t=>t.属性名).IsConcurrencyToken(),下面的例子将SocialSecurityNumber配置为并发检查。
1: Property(t => t.SocialSecurityNumber).IsConcurrencyToken();
10.配置String属性是否支持Unicode内容
默认约定:默认string是Unicode(在SQL Server中是nvarchar)的。
重写约定:下面的例子使用IsUnicode()方法将Name属性配置为varchar类型的。
1: Property(t => t.Name).IsUnicode(false);
11.配置小数的精度和小数位数
默认约定:小数是(18,2)
配 置:使用Property(t=>t.属性名).HasPrecision(n,n)
1: public decimal MilesFromNearestAirport { get; set; }
12.复杂类型
默认复杂类型有以下规则:
(1) 复杂类型没有主键属性
(2) 复杂类型只能包含原始属性。
(3)在其他类中使用复杂类型时,必须表示为非集合类型。
使用DbModelBuilder.ComplexType方法显示配置为复杂类型:
1: modelBuilder.ComplexType<Address>();
13.嵌套的复杂类型
嵌套的复杂类型只需显示配置外层,内层自动继承复杂类型的约定。
14.配置复杂类型的属性
配置复杂类型的属性和配置实体属性一样,具体参考下面的实例。
二、配置属性实例
下面直接给出代码,代码上都有注释。注:下面的实体主要是为了演示用
1: //实体
2: public class Trip
3: {
4: public Guid Identifier { get; set; }
5: public DateTime StartDate { get; set; }
6: public DateTime EndDate { get; set; }
7: public decimal CostUSD { get; set; }
8: public string Description { get; set; }
9: public byte[] RowVersion { get; set; }
10: }
11:
12: //复杂类型
13: public class Address
14: {
15: public int AddressId { get; set; }
16: public string StreetAddress { get; set; }
17: public string City { get; set; }
18: public string State { get; set; }
19: public string ZipCode { get; set; }
20: }
21:
22: //复杂类型
23: public class PersonalInfo
24: {
25: public Measurement Weight { get; set; }
26: public Measurement Height { get; set; }
27: public string DietryRestrictions { get; set; }
28: }
29:
30: //复杂类型
31: public class Measurement
32: {
33: public decimal Reading { get; set; }
34: public string Units { get; set; }
35: }
36:
37: //实体
38: public class Person
39: {
40: public Person()
41: {
42: Address = new Address();
43: Info = new PersonalInfo()
44: {
45: Weight = new Measurement(),
46: Height = new Measurement()
47: };
48: }
49:
50: public int PersonId { get; set; }
51: public int SocialSecurityNumber { get; set; }
52: public string FirstName { get; set; }
53: public string LastName { get; set; }
54: public Address Address { get; set; }
55: public byte[] Photo { get; set; }
56: public PersonalInfo Info { get; set; }
57: public byte[] RowVersion { get; set; }
58: }
59:
60: //对实体Trip的配置,继承自EntityTypeConfiguration<T>
61: public class TripConfiguration : EntityTypeConfiguration<Trip>
62: {
63: public TripConfiguration()
64: {
65: //配置Identifier映射到TripId列,并设为主键,且默认值为newid()
66: HasKey(t => t.Identifier).Property(t => t.Identifier).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).HasColumnName("TripId");
67: //配置CostUSD的精度为20,小数位数为3
68: Property(t => t.CostUSD).HasPrecision(20, 3);
69: //配置Description的长度为500
70: Property(t => t.Description).HasMaxLength(500);
71: //配置RowVersion乐观并发检查
72: Property(t => t.RowVersion).IsRowVersion();
73: }
74: }
75:
76: //对实体Person的配置,继承自EntityTypeConfiguration<T>
77: public class PersonConfiguration : EntityTypeConfiguration<Person>
78: {
79: public PersonConfiguration()
80: {
81: //配置SocialSecurityNumber不允许为空且乐观并发检查
82: Property(t => t.SocialSecurityNumber).IsRequired().IsConcurrencyToken();
83: //配置FirstName不允许为空
84: Property(t => t.FirstName).IsRequired();
85: //配置LastName不允许为空
86: Property(t => t.LastName).IsRequired();
87: //配置Photo映射到数据库的数据类型为image
88: Property(t => t.Photo).HasColumnType("image");
89: //配置RowVersion乐观并发检查
90: Property(t => t.RowVersion).IsRowVersion();
91: }
92: }
93:
94: //对复杂类型Address的配置,继承自ComplexTypeConfiguration<T>
95: public class AddressConfiguration : ComplexTypeConfiguration<Address>
96: {
97: public AddressConfiguration()
98: {
99: //配置AddressId映射到AddressId列
100: Property(t => t.AddressId).HasColumnName("AddressId");
101: //配置StreetAddress长度为100并映射到StreetAddrress列
102: Property(t => t.StreetAddress).HasMaxLength(100).HasColumnName("StreetAddress");
103: //配置State长度为50并映射到State列
104: Property(t => t.State).HasMaxLength(50).HasColumnName("State");
105: //配置City长度为50并映射到City列
106: Property(t => t.City).HasMaxLength(50).HasColumnName("City");
107: //配置ZipCode映射到ZipCode列,不支持Unicode内容,并设为固定长度为6
108: Property(t => t.ZipCode).IsUnicode(false).IsFixedLength().HasMaxLength(6).HasColumnName("ZipCode");
109: }
110: }
111:
112: //对复杂类型PersonalInfo的配置,继承自ComplexTypeConfiguration<T>
113: public class PersonalInfoConfiguration : ComplexTypeConfiguration<PersonalInfo>
114: {
115: public PersonalInfoConfiguration()
116: {
117: //配置DietryRestrictions长度为100
118: Property(t => t.DietryRestrictions).HasMaxLength(100);
119: }
120: }
121:
122: public class BreakAwayContext : DbContext
123: {
124: public DbSet<Trip> Trips { get; set; }
125: public DbSet<Person> People { get; set; }
126:
127: protected override void OnModelCreating(DbModelBuilder modelBuilder)
128: {
129: //注册配置
130: modelBuilder.Configurations.Add(new TripConfiguration());
131: modelBuilder.Configurations.Add(new PersonConfiguration());
132: modelBuilder.Configurations.Add(new AddressConfiguration());
133: modelBuilder.Configurations.Add(new PersonalInfoConfiguration());
134: base.OnModelCreating(modelBuilder);
135: }
136: }
最后生成的数据库结构,如下图所示:
Trips表

People表

三、结束语
本篇文章的内容比较简单,就是一些配置,了解理论知识并熟悉运用是关键。
点击查看《Entity Framework实例详解》系列的其他文章。
如果遇到问题,可以访问Entity Framework社区,网址是www.ef-community.com
Entity Framework实例详解的更多相关文章
- 转:【工欲善其事必先利其器】—Entity Framework实例详解
开始本篇文章之前,先说一下Entity Framework 6 Alpha1在NuGet中已可用,原文链接http://blogs.msdn.com/b/adonet/archive/2012/10/ ...
- 【配置属性】—Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- —Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- 【迁移】—Entity Framework实例详解 转
一.Entity Framework 迁移命令(get-help EntityFramework) Enable-Migrations 启用迁移 Add-Migration 为挂起的Model变化添加 ...
- 【迁移】—Entity Framework实例详解
好久没有在博客园更新博客了,如今都换了新公司.前段时间写了关于EF迁移的文档,今天拿出来作为这个系列的一篇吧. 一.Entity Framework 迁移命令(get-help EntityFrame ...
- 【配置关系】—Entity Framework实例详解
实体间的关系,简单来说无非就是一对一.一对多.多对多,根据方向性来说又分为双向和单向.Code First在实体关系上有以下约定: 1. 两个实体,如果一个实体包含一个引用属性,另一个实体包含一个集合 ...
- [转]C#综合揭秘——Entity Framework 并发处理详解
本文转自:http://www.cnblogs.com/leslies2/archive/2012/07/30/2608784.html 引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的 ...
- Linq实战 之 Linq to Sql及Entity Framework操作详解
Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity f ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...
随机推荐
- 1.值得推荐的C/C++框架和库 (转)
值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的 ...
- sbin/hadoop-daemon.sh: line 165: /tmp/hadoop-hxsyl-journalnode.pid: Permission denied
原来在logs下 该权限,还是不行,以root登陆可以了,但是其他节点是普通用户啊,还会出其他问题,仔细看是/tmp,就是linux根目录下的tmp,改他的权限吧,不知道重启会不会变化.
- CSS3伪类选择器:nth-child()(nth-child(odd)/nth-child(even))
nth-child(odd):奇数 nth-child(even):偶数 使用时,如果是精确到数字时,切记是从同一级别的元素开始计算,而不是指定某个类才开始计算. 比如: <li>< ...
- Android四大组件
Activity 概念 活动是一种可以包含用户界面的组件,主要用于和用户交互.一个应用程序可以包含零个或多个活动. 基本用法 手动创建活动 1. 创建或加载布局 2. 在AndroidManifest ...
- CF 468A 24 Game
题目链接: 传送门 24 Game time limit per test:1 second memory limit per test:256 megabytes Description L ...
- MySQL数据库的高可用性分析
MySQL数据库是目前开源应用最大的关系型数据库,有海量的应用将数据存储在MySQL数据库中.存储数据的安全性和可靠性是生产数据库的关注重点.本文分析了目前采用较多的保障MySQL可用性方案. MyS ...
- iOS开发-二维码
二维码 从ios7开始集成了二维码的生成和读取功能 此前被广泛使用的zbarsdk目前不支持64位处理器 生成二维码的步骤: 倒入CoreImage框架 通过滤镜CIFilter生成二维码 二维码的内 ...
- UML活动图与流程图的区别
http://blog.chinaunix.net/uid-11572501-id-3847592.html UML活动图与流程图的区别 (1).流程图着重描述处理过程,它的主要控制结构是顺序.分支和 ...
- 数据库SQL优化大总结
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 9月23日JavaScript作业----用DIV做下拉列表
例题二.用div做下拉列表 <title>无标题文档</title> <style type="text/css"> *{ margin:0px ...