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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    欢迎访问我的个人博客:程序旅途
  • 相关阅读:
    如何培养编程所需要的逻辑思维?
    CSS教程
    Android中Service(服务)详解
    Tomcat热部署的实现原理
    Java多线程和线程池(转)
    导出Excel表格
    各种时间格式化的转化
    上传多媒体文件到微信公众平台
    发起https请求并获取结果
    Java 将字节转换为十六进制字符串
  • 原文地址:https://www.cnblogs.com/nianming/p/2757997.html
Copyright © 2011-2022 走看看