摘自:http://www.cnblogs.com/nianming/archive/2012/11/07/2757997.html

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 对应表字段的类型的设定配置方法的更多相关文章

  1. Entity Framework Code First (四)Fluent API - 配置属性/类型

    上篇博文说过当我们定义的类不能遵循约定(Conventions)的时候,Code First 提供了两种方式来配置你的类:DataAnnotations 和 Fluent API, 本文将关注 Flu ...

  2. vs2012配置使用entity framework 6

    项目中使用mysql作为数据库,想快速地实现一些数据服务,为了节省开发时间,提升开发效率,性能不是考虑的重点,所以选择了使用ORM框架:Entity Framework.指定了DB的table des ...

  3. 真相大白:为什么Entity Framework不能进行跨数据库查询(附解决方法)

    在上篇随笔中,我们发现Entity Framework在构建SQL语句时,将ToTable("CNBlogsTex.dbo.blog_PostBody")中的"CNBlo ...

  4. Entity Framework Code First (五)Fluent API - 配置关系

    上一篇文章我们讲解了如何用 Fluent API 来配置/映射属性和类型,本文将把重点放在其是如何配置关系的. 文中所使用代码如下 public class Student { public int ...

  5. Entity Framework Code First (五)Fluent API - 配置关系 转载 https://www.cnblogs.com/panchunting/p/entity-framework-code-first-fluent-api-configuring-relationships.html

    上一篇文章我们讲解了如何用 Fluent API 来配置/映射属性和类型,本文将把重点放在其是如何配置关系的. 文中所使用代码如下 public class Student { public int ...

  6. mybatis使用中类属性名和数据库表字段名问题

    起初我以为上述二者必须一致,后来发现也是可以像Hibernate那样在xml文件中进行映射的. <mapper namespace="com.tenghu.mybatis.model. ...

  7. Entity Framework 4.1:复杂类型

    这篇文章将讨论复杂类型. 默认情况下,EF4.1 将类映射到表,这是约定,但是有时候,我们需要模型比表的粒度更细一些. 地址是一个典型的例子,看一下下面的客户类. )] publicstring St ...

  8. Entity framework 7通过代码添加外键关系的方法

    这几天研究Asp.net5,也试着写了一些示例代码,因为网上的资料实在是太少了,所以在此把一些问题的解决方法记录下来,以备后查. 问题: 在EF7中,假如数据库已经存在,并且两个表具有外键关系,但是实 ...

  9. Entity Framework SqlFunctions 教你如何在EF调用sqlserver方法的函数存根

    今天算是研究了一天的SqlFunctions,请教了几个群的牛人,居然发现大伙对这个都比较陌生, 有的甚至直指EF中是不能调用sqlserver里的方法的. 因为之前搞过linq to sql 里面的 ...

随机推荐

  1. 微冷的雨Java基础学习手记(一)

    使用Java理解程序逻辑 之凌波微步 船舶停靠在港湾是很安全的,但这不是造船的目的 北大青鸟五道口原玉明老师出品 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识点时,要 ...

  2. 使用angular中ng-repeat , track by的用处

    我们见到最简单的例子是: <div ng-repeat="link in links" ></div> 如果item的值有重复的,比如links=[&quo ...

  3. Spring<bean>标签是反射来实现的

  4. let命令

    基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. 上面代码在代码块之中,分别用let和var声明了两个变量.然后在代码块之外调 ...

  5. Ajax_03之接收数据

    1.使用XHR接收服务器返回的数据--text 服务器端:  header('Content-Type:text/plain');  echo 'xxx'; 客户端:  xhr.responseTex ...

  6. KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器

    无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...

  7. Windows下安装python2和python3双版本

    现在大家常用的桌面操作系统有:Windows.Mac OS.ubuntu,其中Mac OS 和 ubuntu上都会自带python.这里我们只介绍下Windows(我用的Win10)环境下的pytho ...

  8. jQuery 2.0.3 源码分析Sizzle引擎 - 超级匹配

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 通过Expr.find[ type ]我们找出选择器最右边的最终seed种子合集 通过Sizzle.compile函数编译器 ...

  9. Qt with OpenCascade

    Qt with OpenCascade 摘要Abstract:详细介绍了如何在Qt中使用OpenCascade. 关键字Key Words:Qt.OpenCascade 一.引言 Introducti ...

  10. markdown语法练习

    Markdown练习 这篇文章 主要用于练习markdown各种基本语法. 这篇文章 主要用于练习markdown各种基本语法. 1.标题设置 1.通过在文字下方添加"="或者&q ...