Entity Framework Code First属性映射约定

 

  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<Product>().ToTable("Product");
}

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

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().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<PortalContext>());
} public PortalContext()
: base("name=PortalContext")
{
} public DbSet<Product> Products { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().ToTable("Product", "dbo");
}
}
}

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<Product>().Property(t => t.ProductID)
.HasColumnName("ProductID");
modelBuilder.Entity<Product>().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<Product>().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; }
}
}

  属性设置text数据类型:

[Column("Remark", TypeName = "text")]
public string Remark { get; set; }
modelBuilder.Entity<Category>().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<Product>().HasKey(t => t.ProductID);
}

  若一个表有多个主键时:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().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<Product>().HasKey(t => t.ProductID);
modelBuilder.Entity<Product>().Property(t => t.ProductID)
.HasColumnName("ProductID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Category>().ToTable("Category", "dbo");
modelBuilder.Entity<Category>().HasKey(t => t.CategoryID);
modelBuilder.Entity<Category>().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<Product>().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<Product>().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<Product>
{
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());
}

Entity Framework Code First属性映射约定 转载https://www.cnblogs.com/libingql/p/3352058.html的更多相关文章

  1. Entity Framework Code First属性映射约定

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

  2. 补习知识:Entity Framework Code First属性映射约定

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

  3. Entity Framework Code First关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  4. Entity Framework Code First关系映射约定【l转发】

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  5. Entity Framework Code First数据库连接 转载 https://www.cnblogs.com/libingql/p/3351275.html

    Entity Framework Code First数据库连接   1. 安装Entity Framework 使用NuGet安装Entity Framework程序包:工具->库程序包管理器 ...

  6. Entity Framework Code First学习系列目录

    Entity Framework Code First学习系列说明:开发环境为Visual Studio 2010 + Entity Framework 5.0+MS SQL Server 2012, ...

  7. Entity Framework Code First学习系列

    Entity Framework Code First学习系列目录 Entity Framework Code First学习系列说明:开发环境为Visual Studio 2010 + Entity ...

  8. 【EF】Entity Framework实现属性映射约定

    Entity Framework Code First属性映射约定中“约定”一词,在原文版中为“Convention”,翻译成约定或许有些不好理解,这也是网上比较大多数的翻译,我们就当这是Entity ...

  9. Entity Framework实现属性映射约定

    Entity Framework Code First属性映射约定中“约定”一词,在原文版中为“Convention”,翻译成约定或许有些不好理解,这也是网上比较大多数的翻译,我们就当这是Entity ...

随机推荐

  1. python程序daemon化

    1 直接空格加& python flask_server.py & 最简单的方式 这样还不行,不知道为什么flask server会自动退出. $ nohup python flask ...

  2. CodeForces.1174D.EhabandtheExpectedXORProblem(构造前缀异或和数组)

    题目链接 这道题比赛的时候没做出来,赛后补题的时候发现其实可以构造一个前缀异或和数组,然后根据初始化的第一个值进行填数,但是作为菜鸡的我虽然坚信自己的想法是正确的却想了很久也没有能够构造出来所谓的前缀 ...

  3. 洛谷 P1108 低价购买(LIS,统计方案数)

    传送门 解题思路 看第一个要求,很显然是求最长下降子序列,和LIS几乎一样,很简单,再看第二个问号,求最长下降子序列的方案数??这怎么求? 注意:当二种方案“看起来一样”时(就是说它们构成的价格队列一 ...

  4. neo4j 的cql 语句,增、删、改、查(条件查询)(持续更新)

    前言 因为做一个比赛的项目 ,需要用到 neo4j 数据库,所以要学习其语言cql,特来整理一下他的基本语言. 整片的语句是按照 了 Neo4j 数据库自带的示例 Movie Graph 来写的. 直 ...

  5. 搜索---DFS

    DFS   广度优先一层一层遍历,每一层得到的所有新节点,要用队列存储起来以备下一层遍历的时候再遍历.   而深度优先遍历搜索在得到一个新节点时立即对新节点进行遍历:从节点0出发开始遍历,得到新节点6 ...

  6. Leetcode Lect4 二叉树中的分治法与遍历法

    在这一章节的学习中,我们将要学习一个数据结构——二叉树(Binary Tree),和基于二叉树上的搜索算法. 在二叉树的搜索中,我们主要使用了分治法(Divide Conquer)来解决大部分的问题. ...

  7. Django 的 logging日志文件配置

    在Django的settings配置文件里配置以下信息: import os BASE_LOG_DIR = os.path.join(BASE_DIR , "log") # log ...

  8. 利用vsftpd在Linux构建安全的FTP服务

    最近在机房搭建Linux环境,需要用到了FTP服务,查看了许多的资料,在这里做一下笔记 一.安装 方法一,使用yum命令安装,需要能够连接外网 # yum install vsftpd 方法二,使用安 ...

  9. 88-基于FMC接口的2路CameraLink Base输入子卡模块

    基于FMC接口的2路CameraLink Base输入子卡模块 1.板卡概述 FMC连接器是一种高速多pin的互连器件,广泛应用于板卡对接的设备中,特别是在xilinx公司的所有开发板中都使用.该Ca ...

  10. python基础内置函数

    #取绝对值 #print(abs(-1)) #对序列中的元素进行bool运算,如果可迭代对象为空也返回True # print(all((1,23,))) # print(all({"nam ...