zoukankan      html  css  js  c++  java
  • 【配置属性】—Entity Framework实例详解


    Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表。然而,有时候,不能也不想遵循这些约定,那就需要重写它们。重写默认约定有两种方式:Data AnnotationsFluentAPI。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.配置复杂类型的属性

    配置复杂类型的属性和配置实体属性一样,具体参考下面的实例。

     

    //实体
    public class Trip
    {
        public Guid Identifier { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        public decimal CostUSD { get; set; }
        public string Description { get; set; }
        public byte[] RowVersion { get; set; }
    }
    
    //复杂类型
    public class Address
    {
        public int AddressId { get; set; }
        public string StreetAddress { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
    }
    
    //复杂类型
    public class PersonalInfo
    {
        public Measurement Weight { get; set; }
        public Measurement Height { get; set; }
        public string DietryRestrictions { get; set; }
    }
    
    //复杂类型
    public class Measurement
    {
        public decimal Reading { get; set; }
        public string Units { get; set; }
    }
    
    //实体
    public class Person
    {
        public Person()
        {
            Address = new Address();
            Info = new PersonalInfo()
            {
                Weight = new Measurement(),
                Height = new Measurement()
            };
        }
    
        public int PersonId { get; set; }
        public int SocialSecurityNumber { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Address Address { get; set; }
        public byte[] Photo { get; set; }
        public PersonalInfo Info { get; set; }
        public byte[] RowVersion { get; set; }
    }
    
    //对实体Trip的配置,继承自EntityTypeConfiguration<T>
    public class TripConfiguration : EntityTypeConfiguration<Trip>
    {
        public TripConfiguration()
        {
            //配置Identifier映射到TripId列,并设为主键,且默认值为newid()
            HasKey(t => t.Identifier).Property(t => t.Identifier).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).HasColumnName("TripId");
            //配置CostUSD的精度为20,小数位数为3
            Property(t => t.CostUSD).HasPrecision(20, 3);
            //配置Description的长度为500
            Property(t => t.Description).HasMaxLength(500);
            //配置RowVersion乐观并发检查
            Property(t => t.RowVersion).IsRowVersion();
        }
    }
    
    //对实体Person的配置,继承自EntityTypeConfiguration<T>
    public class PersonConfiguration : EntityTypeConfiguration<Person>
    {
        public PersonConfiguration()
        {
            //配置SocialSecurityNumber不允许为空且乐观并发检查
            Property(t => t.SocialSecurityNumber).IsRequired().IsConcurrencyToken();
            //配置FirstName不允许为空
            Property(t => t.FirstName).IsRequired();
            //配置LastName不允许为空
            Property(t => t.LastName).IsRequired();
            //配置Photo映射到数据库的数据类型为image
            Property(t => t.Photo).HasColumnType("image");
            //配置RowVersion乐观并发检查
            Property(t => t.RowVersion).IsRowVersion();
        }
    }
    
    //对复杂类型Address的配置,继承自ComplexTypeConfiguration<T>
    public class AddressConfiguration : ComplexTypeConfiguration<Address>
    {
        public AddressConfiguration()
        {
            //配置AddressId映射到AddressId列
            Property(t => t.AddressId).HasColumnName("AddressId");
            //配置StreetAddress长度为100并映射到StreetAddrress列
            Property(t => t.StreetAddress).HasMaxLength(100).HasColumnName("StreetAddress");
            //配置State长度为50并映射到State列
            Property(t => t.State).HasMaxLength(50).HasColumnName("State");
            //配置City长度为50并映射到City列
            Property(t => t.City).HasMaxLength(50).HasColumnName("City");
            //配置ZipCode映射到ZipCode列,不支持Unicode内容,并设为固定长度为6
            Property(t => t.ZipCode).IsUnicode(false).IsFixedLength().HasMaxLength(6).HasColumnName("ZipCode");
        }
    }
    
    //对复杂类型PersonalInfo的配置,继承自ComplexTypeConfiguration<T>
    public class PersonalInfoConfiguration : ComplexTypeConfiguration<PersonalInfo>
    {
        public PersonalInfoConfiguration()
        {
            //配置DietryRestrictions长度为100
            Property(t => t.DietryRestrictions).HasMaxLength(100);
        }
    }
    
    public class BreakAwayContext : DbContext
    {
        public DbSet<Trip> Trips { get; set; }
        public DbSet<Person> People { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //注册配置
            modelBuilder.Configurations.Add(new TripConfiguration());
            modelBuilder.Configurations.Add(new PersonConfiguration());
            modelBuilder.Configurations.Add(new AddressConfiguration());
            modelBuilder.Configurations.Add(new PersonalInfoConfiguration());
            base.OnModelCreating(modelBuilder);
        }
    }


  • 相关阅读:
    hdu 1823 Luck and Love 二维线段树
    UVA 12299 RMQ with Shifts 线段树
    HDU 4578 Transformation 线段树
    FZU 2105 Digits Count 线段树
    UVA 1513 Movie collection 树状数组
    UVA 1292 Strategic game 树形DP
    【ACM】hdu_zs2_1003_Problem C_201308031012
    qsort快速排序
    【ACM】nyoj_7_街区最短路径问题_201308051737
    【ACM】nyoj_540_奇怪的排序_201308050951
  • 原文地址:https://www.cnblogs.com/itrena/p/7433835.html
Copyright © 2011-2022 走看看