博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework Code First属性映射约定
阅读量:5774 次
发布时间:2019-06-18

本文共 7480 字,大约阅读时间需要 24 分钟。

  Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API。本文中采用创建Product类为例来说明tity Framework Code First属性映射约定的具体方式。

1. 表名及所有者

  在默认约定的情况下,Entity Framework Code First创建的表名是根据类名的英语复数形式,创建的表所有者为dbo,可以通过重写约定来指定表名及表的所有者。

1.1 Data Annotation方式

  在使用Data Annotation方式进行Entity Framework Code First与数据库映射之前,需要先添加命名空间引用。

using System.ComponentModel.DataAnnotations.Schema;

  为类配置对应表名:

[Table("Product")]public class Product

  为类配置对应表名并指定表的所有者:

[Table("Product", Schema = "dbo")]public class Product

1.2 Fluent API方式

  Fluent API实现配置Entity Framework Code First与数据库映射关系主要是通过继承DbContext并重写其中的OnModelCreating方法来进行的。在本文中新建类文件PortalContext.cs继承DbContext。

  在继承DbContext之前,添加命名空间引用。

using System.Data.Entity;

  重写OnModelCreating方法,配置类对应于数据库中的表名:

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().ToTable("Product");}

  重写OnModelCreating方法,配置类对应于数据库中的表名,并指定表的所有者:

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().ToTable("Product", "dbo");}

  到此处PortalContext.cs的完整代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data.Entity;using Portal.Entities;namespace Portal{    public class PortalContext : DbContext    {        static PortalContext()        {            Database.SetInitializer(new DropCreateDatabaseIfModelChanges
()); } public PortalContext() : base("name=PortalContext") { } public DbSet
Products { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity
().ToTable("Product", "dbo"); } }}
View Code

2. 字段名、长度、数据类型及是否可空

  在默认约定的情况下,Entity Framework Code First创建的列名与类的属性名相同,可以根据需要进行重新指定类属性与列名之间的映射关系。

2.1 Data Annotation方式

[Column("ProductID")]public int ProductID { get; set; } [MaxLength(100)][Required, Column("ProductName")]public string ProductName { get; set; }

  在使用Required特性(Attribute)设置字段不允许为空时,需要添加命名空间引用:

using System.ComponentModel.DataAnnotations;

1.2 Fluent API方式

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().Property(t => t.ProductID) .HasColumnName("ProductID"); modelBuilder.Entity
().Property(t => t.ProductName) .IsRequired() .HasColumnName("ProductName")      .HasMaxLength(100);}

  在默认情况下,int类型的属性生成的列名对应SQL SERVER列int类型;而String类型的属性则对应SQL SERVER列的NVARCHAR类型。若类的字符串类型属性未设置MaxLength,则生成对应的列类型为NVARCHAR(MAX)。

  为属性指定对应的SQL SERVER数据类型:

[Column("UnitPrice", TypeName = "MONEY")]public decimal UnitPrice { get; set; }
modelBuilder.Entity
().Property(t => t.UnitPrice) .HasColumnName("UnitPrice") .HasColumnType("MONEY");

  到此步,Product.cs类文件的完整代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;namespace Portal.Entities{    [Table("Product", Schema = "dbo")]    public class Product    {        [Column("ProductID")]        public int ProductID { get; set; }        [MaxLength(100)]        [Required, Column("ProductName")]        public string ProductName { get; set; }        [Column("UnitPrice", TypeName = "MONEY")]        public decimal UnitPrice { get; set; }    }}
View Code

  属性设置text数据类型:

[Column("Remark", TypeName = "text")]public string Remark { get; set; }
modelBuilder.Entity
().Property(t => t.Remark) .HasColumnName("Remark") .HasColumnType("text");

3. 主键

  Entity Framework Code First的默认主键约束:属性名为[ID]或[类名 + ID]。如在Product类中,Entity Framework Code First会根据默认约定将类中名称为ID或ProductID的属性设置为主键。Entity Framework Code First主键的默认约定也一样可以进行重写,重新根据需要进行设置。

3.1 Data Annotation方式

using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;
[Key][Column("ProductID")]public int ProductID { get; set; }

3.2 Fluent API方式

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().HasKey(t => t.ProductID);}

  若一个表有多个主键时:

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().HasKey(t => new { t.KeyID, t.CandidateID });}

4、数据库自动生成字段值

  Entity Framework Code First对于int类型的主键,会自动的设置其为自动增长列。但有时我们确实不需是自动增长的,可以通过以下方式进行取消自动增长。

4.1 Data Annotation方式

[Key][Column("ProductID")][DatabaseGenerated(DatabaseGeneratedOption.None)]public int ProductID { get; set; }
[Key][Column("CategoryID")][DatabaseGenerated(DatabaseGeneratedOption.Identity)]public int CategoryID { get; set; }

4.2 Fluent API方式

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().HasKey(t => t.ProductID); modelBuilder.Entity
().Property(t => t.ProductID) .HasColumnName("ProductID") .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);}
protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().ToTable("Category", "dbo"); modelBuilder.Entity
().HasKey(t => t.CategoryID); modelBuilder.Entity
().Property(t => t.CategoryID) .HasColumnName("CategoryID") .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);}

5. 数字类型长度及精度

  在Product类中,UnitPrice表示单价,对于价格类的字段,我们通常会希望其保留2为小数。这时可以使用Fluent API进行设置,且Data Annotation不支持该设置。

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().Property(t => t.UnitPrice) .HasColumnName("UnitPrice") .HasPrecision(18, 2);}

6、非数据库字段属性

  在类中,如果有一些属性不需要映射到对应生成的数据表中,可以通过以下方式设置。

6.1 Data Annotation方式

[NotMapped]public string Remark { get; set; }

6.2 Fluent API方式

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Entity
().Ignore(t => t.Remark);}

7. Fluent API配置Configuration映射类

  在使用Fluent API进行Entity Framework Code First数据库映射时,除了以上的在重写OnModelCreating方法中直接对Entity进行配置之外,也可以对Configurations进行配置。这时可以先写一个单独的类,将数据表的全部映射要求都写在构造函数中。

  ProductMap.cs类

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel.DataAnnotations.Schema;using System.Data.Entity.ModelConfiguration;using Portal.Entities;namespace Portal.Mapping{    public class ProductMap : EntityTypeConfiguration
{ public ProductMap() { // Primary Key this.HasKey(t => t.ProductID); // Properties this.Property(t => t.ProductID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); this.Property(t => t.ProductName) .IsRequired() .HasMaxLength(100); // Table & Column Mappings this.ToTable("Product"); this.Property(t => t.ProductID).HasColumnName("ProductID"); this.Property(t => t.ProductName).HasColumnName("ProductName"); this.Property(t => t.UnitPrice) .HasColumnName("UnitPrice") .HasPrecision(18, 2); } }}

  有了上面的映射类之后,在重写OnModelCreating方法中则可以直接调用映射类,从而减少了OnModelCreating方法的复杂度,同时也增强了代码维护的可读性。

protected override void OnModelCreating(DbModelBuilder modelBuilder){    modelBuilder.Configurations.Add(new ProductMap());}

转载于:https://www.cnblogs.com/libingql/p/3352058.html

你可能感兴趣的文章
CentOS7 yum 安装git
查看>>
html5视频标签
查看>>
JAVA进阶-注解
查看>>
三元表达式之理解/jquery源代码分析之$.inArray实现
查看>>
STM32 mdk软件仿真时过不去时钟的问题
查看>>
Spark Streaming概念学习系列之Spark Streaming容错
查看>>
单例模式
查看>>
老旧的金融机构,是时候赶赶云计算的时髦了
查看>>
用友网络陈强兵:企业互联网需解决五大问题
查看>>
SMA推出Powerwall兼容Sunny Boy Storage逆变器
查看>>
云路由 vyatta 体验(二)NAT
查看>>
Python version 2.7 required, which was not foun...
查看>>
centos7.3 下安装 composer,解决Failed to decode zlib stream错误
查看>>
Git 常用命令
查看>>
在Postgres 数据库中生成36位的UUID代码
查看>>
小黑小波比.功能测试登录用户
查看>>
Java enum用法详解
查看>>
去云端的多条途径
查看>>
Docker容器从一知半解到入门
查看>>
关于“方法参数”
查看>>