Entity Framework使用Fluent API配置案例

一、配置主键

要显式将某个属性设置为主键,可使用 HasKey 方法。在以下示例中,使用了 HasKey 方法对 Product 类型配置 ProductId 主键。

1、新加Product类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Model
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public decimal Price { get; set; }
    }
}

2、新建ProductMap类,用来设置主键

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using FluentAPI.Model;

namespace FluentAPI.Data.FluentAPIMap
{
    public class ProductMap : EntityTypeConfiguration<Product>
    {
        public ProductMap()
        {
            //使用 HasKey 方法对 Product 类型配置 ProductId 主键。
            this.HasKey(p => p.ProductId);
        }
    }
}

3、查看数据库

二、配置复合主键

以下示例配置要作为Department 类型的组合主键的DepartmentID 和 Name 属性。

1、创建Department类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Model
{
    public class Department
    {
        public int DepartmentId { get; set; }
        public string Name { get; set; }
        public decimal Budget { get; set; }
        public DateTime StartDate { get; set; }
    }
}

2、创建DepartmentMap类,用来设置复合主键

using FluentAPI.Model;
using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Data.FluentAPIMap
{
    public class DepartmentMap : EntityTypeConfiguration<Department>
    {
        public DepartmentMap()
        {
            // 使用匿名类的方式配置DepartmentId和Name作为复合主键
            this.HasKey(p => new {p .DepartmentId,p.Name});
        }
    }
}

3、查看数据库

使用EF的数据迁移,然后查看数据库表

三、关闭数值主键的标识

数值主键的标识DatabaseGeneratedOption是一个枚举值,该枚举值具有下面三个值:

DatabaseGeneratedOption.None:关闭数值主键。
DatabaseGeneratedOption.Identity:设置数值主键 自动增长 ,
DatabaseGeneratedOption.Computed :数值主键的值由计算得到(此列将无法插入值)。

1、设置关闭数值主键

using FluentAPI.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Data.FluentAPIMap
{
    public class DepartmentMap : EntityTypeConfiguration<Department>
    {
        public DepartmentMap()
        {
            // 使用匿名类的方式配置DepartmentId和Name作为复合主键
            this.HasKey(p => new {p .DepartmentId,p.Name});

            // 以下示例将DepartmentID 属性设置为System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None,以指示该值不由数据库生成。
            this.Property(p => p.DepartmentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        }
    }
}

2、插入数据库表的时候DepartmentId列要显示的指定值:

INSERT INTO Departments VALUES (1, '人事部',12.3,GETDATE());

四、指定属性的最大长度

HasMaxLength可以设置表中列的最大长度。

using FluentAPI.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Data.FluentAPIMap
{
    public class DepartmentMap : EntityTypeConfiguration<Department>
    {
        public DepartmentMap()
        {
            // 使用匿名类的方式配置DepartmentId和Name作为复合主键
            this.HasKey(p => new {p .DepartmentId,p.Name});

            // 以下示例将DepartmentID 属性设置为System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None,以指示该值不由数据库生成。
            //this.Property(p => p.DepartmentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            //  以下示例将DepartmentID 属性设置为System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None,以指示该值由数据库自动生成。
            //this.Property(p => p.DepartmentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            //Name属性不应超过 50 个字符。如果其值超过 50 个字符,则出现 DbEntityValidationException 异常。
            //如果 Code First 基于此模型创建数据库,它还会将 Name 列的最大长度设置为50 个字符。
            this.Property(p => p.Name).HasMaxLength(50);

        }
    }
}

五、将属性配置为必需

using FluentAPI.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Data.FluentAPIMap
{
    public class DepartmentMap : EntityTypeConfiguration<Department>
    {
        public DepartmentMap()
        {
            // 使用匿名类的方式配置DepartmentId和Name作为复合主键
            this.HasKey(p => new {p .DepartmentId,p.Name});

            // 以下示例将DepartmentID 属性设置为System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None,以指示该值不由数据库生成。
            //this.Property(p => p.DepartmentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            //  以下示例将DepartmentID 属性设置为System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None,以指示该值由数据库自动生成。
            //this.Property(p => p.DepartmentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            //Name属性不应超过 50 个字符。如果其值超过 50 个字符,则出现 DbEntityValidationException 异常。
            //如果 Code First 基于此模型创建数据库,它还会将 Name 列的最大长度设置为50 个字符。
            this.Property(p => p.Name).HasMaxLength(50);

            /*
            Name属性是必需的。如果不指定 Name,则出现 DbEntityValidationException 异常。如果 Code First 基于此模型创建数据库,则用于存储此属性的列将不可为空。
            */
            this.Property(p => p.Name).IsRequired();

        }
    }
}

六、指定不将CLR 属性映射到数据库中的列

using FluentAPI.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Data.FluentAPIMap
{
    public class DepartmentMap : EntityTypeConfiguration<Department>
    {
        public DepartmentMap()
        {
            // 使用匿名类的方式配置DepartmentId和Name作为复合主键
            this.HasKey(p => new {p .DepartmentId,p.Name});

            // 以下示例将DepartmentID 属性设置为System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None,以指示该值不由数据库生成。
            //this.Property(p => p.DepartmentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            //  以下示例将DepartmentID 属性设置为System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None,以指示该值由数据库自动生成。
            //this.Property(p => p.DepartmentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            //Name属性不应超过 50 个字符。如果其值超过 50 个字符,则出现 DbEntityValidationException 异常。
            //如果 Code First 基于此模型创建数据库,它还会将 Name 列的最大长度设置为50 个字符。
            this.Property(p => p.Name).HasMaxLength(50);

            /*
            Name属性是必需的。如果不指定 Name,则出现 DbEntityValidationException 异常。如果 Code First 基于此模型创建数据库,则用于存储此属性的列将不可为空。
            */
            this.Property(p => p.Name).IsRequired();

            /*
           以下示例显示如何指定CLR 类型的属性不映射到数据库中的列。
           Ignore 等同于数据注解NotMapped
           */
            this.Ignore(p => p.Budget);

        }
    }
}

七、将CLR 属性映射到数据库中的特定列

HasColumnName可以用来设置映射到数据库表中列的列名。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using FluentAPI.Model;
using System.ComponentModel.DataAnnotations.Schema;

namespace FluentAPI.Data.FluentAPIMap
{
    public class ProductMap : EntityTypeConfiguration<Product>
    {
        public ProductMap()
        {
            //使用 HasKey 方法对 Product 类型配置 ProductId 主键。
            this.HasKey(p => p.ProductId);

            /*
             * 以下示例将Price CLR 属性映射到ProductPrice 数据库列。
             */
            this.Property(p => p.Price).HasColumnName("ProductPrice");
        }
    }
}

八、配置字符串属性是否支持Unicode 内容

IsUnicode()方法可以用来设置是否支持Unicode字符,该方法有两个重载函数。

1、没有参数的重载,默认支持Unicode字符

2、有参数的重载,参数为bool值,true支持Unicode,false不支持Unicode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using FluentAPI.Model;
using System.ComponentModel.DataAnnotations.Schema;

namespace FluentAPI.Data.FluentAPIMap
{
    public class ProductMap : EntityTypeConfiguration<Product>
    {
        public ProductMap()
        {
            //使用 HasKey 方法对 Product 类型配置 ProductId 主键。
            this.HasKey(p => p.ProductId);

            /*
             * 以下示例将Price CLR 属性映射到ProductPrice 数据库列。
             */
            this.Property(p => p.Price).HasColumnName("ProductPrice");

            /*
            * 默认情况下,字符串为Unicode(SQLServer 中的nvarchar)。您可以使用IsUnicode 方法指定字符串应为varchar 类型。
            */
            this.Property(p => p.PlaceOfOrigin).IsUnicode(false);
        }
    }
}

查看数据库列类型:

九、配置数据库列的数据类型

HasColumnType 方法支持映射到相同基本类型的不同表示。

/*
HasColumnType 方法支持映射到相同基本类型的不同表示。使用此方法并不支持在运行时执行任何数据转换。
* 请注意,IsUnicode 是将列设置为 varchar 的首选方法,因为它与数据库无关。
*/
this.Property(p => p.Name).HasColumnType("varchar");

十、配置复杂类型的属性

1、新建类Course,里面有一个Department类型的属性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPIApp.Model
{
    public class Course
    {
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }
        public virtual Department Department { get; set; }
    }
}
using FluentAPI.Model;
using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FluentAPI.Data.FluentAPIMap
{
    public class CourseMap : EntityTypeConfiguration<Course>
    {
        public CourseMap()
        {
            /*可以使用点表示法访问复杂类型的属性。
              设置Course类里面的Department属性的Name的最大长度是32
             */
            this.Property(p => p.Department.Name).HasMaxLength(32);
        }
    }
}

十一、将CLR 实体类型映射到数据库中的特定表

/*Department 的所有属性都将映射到名为 t_ Department 的表中的列。*/
ToTable("t_Department");
/*您也可以这样指定架构名称:*/
ToTable("t_Department", "school");

代码地址:点此下载

到此这篇关于Entity Framework使用Fluent API配置案例的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Entity Framework Core实现Like查询详解

    在Entity Framework Core 2.0中增加一个很酷的功能:EF.Functions.Like(),最终解析为SQL中的Like语句,以便于在 LINQ 查询中直接调用. 不过Entity Framework 中默认提供了StartsWith.Contains和EndsWith方法用于解决模糊查询,那么为什么还要提供EF.Functions.Like,今天我们来重点说说它们之间的区别. 表结构定义 在具体内容开始之前,我们先简单说明一下要使用的表结构. public class C

  • Entity Framework使用配置伙伴创建数据库

    在上一篇文章中讲了如何使用fluent API来创建数据表,不知道你有没有注意到一个问题.上面的OnModelCreating方法中,我们只配置了一个类Product,也许代码不是很多,但也不算很少,如果我们有1000个类怎么办?都写在这一个方法中肯定不好维护.EF提供了另一种方式来解决这个问题,那就是为每个实体类单独创建一个配置类.然后在OnModelCreating方法中调用这些配置伙伴类. 创建Product实体类: using System; using System.Collectio

  • Entity Framework系统架构与原理介绍

    一.Entity Framework概要 Entity Framework是微软的Object Relational Mapper(对象关系映射),也就是我们平常说的ORM,它可以让应用程序开发者将关系型数据作为业务模型来使用,也消除了开发者为数据访问编写的绝大多数管道代码的需要(比如使用ADO.NET).Entity Framework提供了一个综合的.基于模型的系统,通过摆脱为所有的领域模型编写相似的数据访问代码,使得开发者创建数据访问层是如此之简单.Entity Framework的首发版

  • Entity Framework中执行sql语句

    一.为什么要在EF中执行SQL语句 使用EF操作数据库,可以避免写SQL语句,完成使用Linq实现,但为什么还要在EF中执行SQL语句呢.如果要写SQL语句,完全可以使用ADO.NET来操作数据库.这样说虽然没错,可是有些时候使用EF操作数据库还是有一些不方便的地方,例如:如果要修改某一条记录,按照EF的正常流程走,需要先把要修改的数据查询出来,然后在去修改,这样不仅麻烦而且性能也低,这时直接使用EF执行SQL语句性能会提高很多.而使用EF执行SQL又比ADO.NET方便,特别是在执行查询语句的

  • Entity Framework实现数据迁移

    一.合并和迁移 1.合并 合并是指“新的实体模型映射到数据库中,更新其结构”,例如:新增了实体类,表现在数据库中就是新增加实体类对应的数据表.删除了实体类,表现在数据库中就是删除了实体类对应的数据表.在一个已经存在的实体类中增加属性,表现在数据库中就是在实体类对应的数据表中新增加字段.在一个已经存在的实体类中删除属性,表现在数据库中就是在实体类对应的数据表中删除字段.修改一个已经存在的实体类中属性的名称或类型,表现在数据库中就是修改实体类对应的数据表中字段的名称或类型. 2.迁移 迁移是指“在更

  • Entity Framework常用查询语句

    方法一:Linq to Entitie var info = from p in entity.Users where p.ID >= 10 orderby p.ID descending select p; foreach (var item in info) { Console.WriteLine("ID:" + item.ID + " " + "登录名:" + item.LoginName + " " + &quo

  • Entity Framework Core批处理SQL语句

    在Entity Framework Core (EF Core)有许多新的功能,最令人期待的功能之一就是批处理语句.那么批处理语句是什么呢?批处理语句意味着它不会为每个插入/更新/删除语句发送单独的请求,它将在数据库的单次请求中批量执行多个语句.在这篇文章中,让我们看看它是如何工作的,并将结果与EF6进行比较. EF Core将一次准备多个语句,然后在单次请求中执行它们,所以能提供了更好的性能和速度.让我们看看它是如何工作的.我们将借助SQL Server Profiler来捕获实际生成和执行的

  • Entity Framework Core生成列并跟踪列记录

    注意:我使用的是 Entity Framework Core 2.0 (2.0.0-preview2-final).正式版发布时,功能可能存在变动. 当您设计数据库时,有时需要添加列以跟踪记录何时更改,以及谁进行了更改.例如,您添加以下列: CreatedAt CreatedBy LastUpdatedAt LastUpdatedBy 您可以轻松地使用默认值和触发器来处理CreatedAt和LastUpdatedAt列.老实说,创建触发器是件无聊的事情,你也不想自己做.此外,很难设置用户名,因为

  • Entity Framework Core中执行SQL语句和存储过程的方法介绍

    无论ORM有多么强大,总会出现一些特殊的情况,它无法满足我们的要求.在这篇文章中,我们介绍几种执行SQL的方法. 表结构 在具体内容开始之前,我们先简单说明一下要使用的表结构. public class Category { public int CategoryID { get; set; } public string CategoryName { get; set; } } 在Category定义了两个字段:CategoryID.CategoryName. public class Sam

  • Entity Framework使用DbModelBuilder API创建表结构

    DbContext类有一个OnModelCreating方法,它用于流利地配置领域类到数据库模式的映射.下面我们以fluent API的方式来定义映射.首先,先将Product类注释掉,重新编写该类,重新编写后的Product类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EFFluent

随机推荐