你的位置:首页 > ASP.net教程

[ASP.net教程]【配置属性】—Entity Framework 对应表字段的类型的设定配置方法

摘自: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表

QQ截图20121106235602

People表

QQ截图20121106235647