zoukankan      html  css  js  c++  java
  • 【配置属性】—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表

    QQ截图20121106235602

    People表

    QQ截图20121106235647

    三、结束语

    本篇文章的内容比较简单,就是一些配置,了解理论知识并熟悉运用是关键。

    点击查看《Entity Framework实例详解》系列的其他文章。

    如果遇到问题,可以访问Entity Framework社区,网址是www.ef-community.com

    作者:BobTian
    出处http://nianming.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 
    欢迎访问我的个人博客:程序旅途 
  • 相关阅读:
    UVA 408 (13.07.28)
    linux概念之用户,组及权限
    Java实现 蓝桥杯 历届试题 网络寻路
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 九宫重排
    Java实现 蓝桥杯 历届试题 九宫重排
  • 原文地址:https://www.cnblogs.com/Jeely/p/10954006.html
Copyright © 2011-2022 走看看