ASP.NET Core 3.1系列(16)——EFCore之Code First

这篇具有很好参考价值的文章主要介绍了ASP.NET Core 3.1系列(16)——EFCore之Code First。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、前言

前一篇博客介绍了EFCore中的DB First开发模式,该模式可以根据数据库生成实体类和数据库上下文,因此适用于数据库已经存在的场景。而与之相对应的,Code First主要是根据自定义的实体类和数据库上下文反向构建数据库,因此也可以看做是DB First的逆过程,下面开始介绍。

2、定义实体类和数据库上下文

新建一个Web API项目,使用NuGet引入如下组件:

Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools

新建实体类Author、数据库上下文DaoDbContext,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft
DaoDbContext的代码如下所示:

using App.Models;
using Microsoft.EntityFrameworkCore;

namespace App.Context
{
    public class DaoDbContext : DbContext
    {
        public DaoDbContext()
        {

        }

        public DaoDbContext(DbContextOptions<DaoDbContext> options) : base(options)
        {

        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Data Source=DSF-PC;Initial Catalog=Dao;User ID=sa;Password=123456;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Author>();
            base.OnModelCreating(modelBuilder);
        }

        public virtual DbSet<Author> Author { get; set; }
    }
}

Author先不用添加代码:

namespace App.Models
{
    public class Author
    {

    }
}

3、基于Data Annotations的Code First

3.1、定义主键——[Key]

Code First模式通过实体类生成数据表,而数据表必然含有一个主键,在Code First中可以使用[Key]来标识实体类中的主键字段,代码如下:

using System.ComponentModel.DataAnnotations;

namespace App.Models
{
    public class Author
    {
        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration m1

然后更新数据库:

Update-Database

打开数据库查看新生成的Author数据表,可以看到主键字段Id已经生成,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

3.2、定义文本长度——[StringLength]、[MinLength]、[MaxLength]

在数据库中,部分字段的类型可能是varcharnvarchar,此时可以通过[StringLength][MinLength][MaxLength]对其长度进行标识。在Author中新增NameAddress字段,代码如下:

using System.ComponentModel.DataAnnotations;

namespace App.Models
{
    public class Author
    {
        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [MinLength(2)]
        [MaxLength(20)]
        public string Name { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        [StringLength(40)]
        public string Address { get; set; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration m2

然后更新数据库:

Update-Database

打开数据库查看新生成的Author数据表,可以看到NameAddress字段已经生成,其中Name字段最大长度为20Address字段最大长度为40,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

3.3、字段不能为NULL——[Required]

在数据表中,主键不能为NULL。如果希望其他字段也不能为NULL,则可以使用[Required]进行标识,下面对Author进行修改,规定Name字段不能为空,代码如下:

using System.ComponentModel.DataAnnotations;

namespace App.Models
{
    public class Author
    {
        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [Required]
        [MinLength(2)]
        [MaxLength(20)]
        public string Name { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        [MinLength(5)]
        [MaxLength(40)]
        public string Address { get; set; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration m3

然后更新数据库:

Update-Database

打开数据库查看新生成的Author数据表,可以看到Name被定义为不能为NULL,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

3.4、忽略映射字段——[NotMapped]

在某些情况下,实体类中的部分字段并不需要在数据库中生成对应的字段,此时就可以使用[NotMapped]进行标识。下面对Author进行修改,添加一个Info字段,代码如下:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace App.Models
{
    public class Author
    {
        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [Required]
        [MinLength(2)]
        [MaxLength(20)]
        public string Name { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        [MinLength(5)]
        [MaxLength(40)]
        public string Address { get; set; }

        /// <summary>
        /// 信息
        /// </summary>
        [NotMapped]
        public string Info { get => $"姓名:{Name},地址:{Address}"; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration m4

然后更新数据库:

Update-Database

打开数据库查看新生成的Author数据表,可以看到实体类中的Info字段并没有创建对应的字段,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

3.5、定义列名——[Column]

在某些情况下,我们希望手动设置某个字段在数据表中对应的列名,此时就可以使用[Column]进行标识,下面对Author进行修改,给每个字段加上前缀Author_,代码如下:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace App.Models
{
    public class Author
    {
        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [Required]
        [MinLength(2)]
        [MaxLength(20)]
        [Column("Author_Name")]
        public string Name { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        [MinLength(5)]
        [MaxLength(40)]
        [Column("Author_Address")]
        public string Address { get; set; }

        /// <summary>
        /// 信息
        /// </summary>
        [NotMapped]
        public string Info { get => $"姓名:{Name},地址:{Address}"; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration m5

然后更新数据库:

Update-Database

打开数据库查看新生成的Author数据表,可以看到数据表中的字段已经加上了Author_前缀,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

3.6、定义表名——[Table]

如果希望手动设置数据表名称,则可以使用[Table]进行标识,下面对Author进行修改,将表名设置为T_AuthorInfo,代码如下:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace App.Models
{
    [Table("T_AuthorInfo")]
    public class Author
    {
        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [Required]
        [MinLength(2)]
        [MaxLength(20)]
        [Column("Author_Name")]
        public string Name { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        [MinLength(5)]
        [MaxLength(40)]
        [Column("Author_Address")]
        public string Address { get; set; }

        /// <summary>
        /// 信息
        /// </summary>
        [NotMapped]
        public string Info { get => $"姓名:{Name},地址:{Address}"; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration m6

然后更新数据库:

Update-Database

打开数据库查看新生成的Author数据表,可以看到数据表的名称已经修改为T_AuthorInfo,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

3.7、定义外键——[ForeignKey]

如果存在一对多的情况,则可以使用[ForeignKey]对外键进行标识。新建一个实体类Book,该类包含一个外键AuthorId,代码如下:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace App.Models
{
    public class Book
    {
        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }

        /// <summary>
        /// 书名
        /// </summary>
        [StringLength(30)]
        public string BookName { get; set; }

        /// <summary>
        /// 外键
        /// </summary>
        public int? AuthorId { get; set; }

        /// <summary>
        /// 导航属性
        /// </summary>
        [ForeignKey("AuthorId")]
        public virtual Author Author { get; set; }
    }
}

由于AuthorBook是一对多的关系,因此Author中需要定义一个Book集合,代码如下:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace App.Models
{
    public class Author
    {
        public Author()
        {
            Book = new HashSet<Book>();
        }

        /// <summary>
        /// 主键
        /// </summary>
        [Key]
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [Required]
        [MinLength(2)]
        [MaxLength(20)]
        public string Name { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        [MinLength(5)]
        [MaxLength(40)]
        public string Address { get; set; }

        /// <summary>
        /// 信息
        /// </summary>
        [NotMapped]
        public string Info { get => $"姓名:{Name},地址:{Address}"; }

        /// <summary>
        /// 导航属性
        /// </summary>
        public virtual ICollection<Book> Book { get; set; }
    }
}

最后更新一下DaoDbContext,代码如下:

using App.Models;
using Microsoft.EntityFrameworkCore;

namespace App.Context
{
    public class DaoDbContext : DbContext
    {
        public DaoDbContext()
        {

        }

        public DaoDbContext(DbContextOptions<DaoDbContext> options) : base(options)
        {

        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Data Source=10.8.59.253;Initial Catalog=Dao;uid=sa;pwd=gis1a6b7c!Z;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Author>();
            modelBuilder.Entity<Book>();
            base.OnModelCreating(modelBuilder);
        }

        public virtual DbSet<Author> Author { get; set; }
        public virtual DbSet<Book> Book { get; set; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration m7

然后更新数据库:

Update-Database

打开数据库,可以看到数据表Book已经生成,同时外键AuthorId也已经成功创建,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft
到此为止,我们已经熟悉了基本的Code First操作。其实Data Annotations中还包含很多其他的属性标识,如[Range][Comment][RegularExpression]等,有兴趣的同志可自行深入研究。

4、基于Fluent API的Code First

上面介绍了基于Data AnnotationsCode First,该模式主要是通过给实体类打标签定义数据表。在EF Core中,还有一种使用Fluent API定义数据表的方法,下面开始介绍其使用方法,项目结构如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

定义AuthorBook,代码如下:

using System.Collections.Generic;

namespace App.Model
{
    public class Author
    {
        public Author()
        {
            Book = new HashSet<Book>();
        }

        /// <summary>
        /// 主键
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        public string Address { get; set; }

        /// <summary>
        /// 导航属性
        /// </summary>
        public virtual ICollection<Book> Book { get; set; }
    }
}
namespace App.Model
{
    public class Book
    {
        /// <summary>
        /// 主键
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 书名
        /// </summary>
        public string BookName { get; set; }

        /// <summary>
        /// 外键
        /// </summary>
        public int? AuthorId { get; set; }

        /// <summary>
        /// 导航属性
        /// </summary>
        public virtual Author Author { get; set; }
    }
}

AuthorConfigurationBookConfiguration需要继承IEntityTypeConfiguration<>接口,代码如下:

using App.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace App.Config
{
    public class AuthorConfiguration : IEntityTypeConfiguration<Author>
    {
        public void Configure(EntityTypeBuilder<Author> builder)
        {
            // 定义主键
            builder.ToTable("Author").HasKey(p => p.Id);
            // 定义字段Name
            builder.Property(p => p.Name).IsRequired().HasMaxLength(20);
            // 定义字段Address
            builder.Property(p => p.Address).HasMaxLength(40);
        }
    }
}
using App.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace App.Config
{
    public class BookConfiguration : IEntityTypeConfiguration<Book>
    {
        public void Configure(EntityTypeBuilder<Book> builder)
        {
            // 定义主键
            builder.ToTable("Book").HasKey(p => p.Id);
            // 定义字段BookName
            builder.Property(p => p.BookName).IsRequired().HasMaxLength(20);
            // 定义外键AuthorId
            builder.HasOne(p => p.Author)
                   .WithMany(p => p.Book)
                   .HasForeignKey(p => p.AuthorId)
                   .OnDelete(DeleteBehavior.Cascade)
                   .HasConstraintName("FK_Book_Author");
        }
    }
}

最后添加DaoDbContext部分,代码如下:

using App.Config;
using App.Model;
using Microsoft.EntityFrameworkCore;

namespace App.Context
{
    public class DaoDbContext : DbContext
    {
        public DaoDbContext()
        {

        }

        public DaoDbContext(DbContextOptions<DaoDbContext> options) : base(options)
        {

        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Data Source=DSF-PC;Initial Catalog=Dao;User ID=sa;Password=123456;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new AuthorConfiguration());
            modelBuilder.ApplyConfiguration(new BookConfiguration());
            base.OnModelCreating(modelBuilder);
        }

        public virtual DbSet<Author> Author { get; set; }
        public virtual DbSet<Book> Book { get; set; }
    }
}

NuGet控制台中输入如下命令:

Add-Migration mig

然后更新数据库:

Update-Database

打开数据库,可以看到数据表AuthorBook已经生成,同时外键AuthorId也已经成功创建,如下图所示:

efcore codefirst,ASP.NET Core,C#,asp.net,数据库,microsoft

5、结语

本文主要介绍了EF Core中的Code First模式,在实际开发过程中更推荐使用Fluent API的方式,因为该方法耦合性较低且更加灵活。文章来源地址https://www.toymoban.com/news/detail-798055.html

到了这里,关于ASP.NET Core 3.1系列(16)——EFCore之Code First的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • asp.net core EFCore 属性配置与DbContext

    Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。用于程序中的class类和数据库中的表互相之间建立映射关系。在学习过程中,EFCore中的属性配置显的尤为重要它是学习好asp.net core的基础是配置数据库表结构的重要基石。本篇内容为

    2024年02月07日
    浏览(63)
  • asp.net core 6.0 efcore +sqlserver增删改查的demo

    下面是一个使用ASP.NET Core 5.0和Entity Framework Core进行增删改查操作的示例。 首先,创建一个空的ASP.NET Core 6.0 Web应用程序项目。 然后,安装以下NuGet包: Microsoft.EntityFrameworkCore.SqlServer Microsoft.EntityFrameworkCore.Tools 接下来,创建一个数据库上下文类,用于定义实体类和数据库连接

    2024年02月13日
    浏览(44)
  • ASP.Net Core Web Api+EFCore+MySql实现动态查询(保姆教学)

    本文会详细讲解如何从打开文件到第一个API开发完成,过程十分详细,是基于学习入门。 现在让我们开始吧! 打开VS(演示用的Visual Studio2022) 第一步我们选择创建新项目   第二步 选择开发语言以及应用程序 我们选择C# -所有平台-Web API.找到 ASP.NET Core Web API 应用   这里应用

    2024年02月12日
    浏览(43)
  • Asp.net Core系列学习(1)

    ASP.NET Core 是一个跨平台的高性能开源 框架 ,用于生成启用云且连接 Internet 的新式应用。 使用 ASP.NET Core,可以: 生成 Web 应用和服务、物联网 (IoT) 应用和移动后端。 在 Windows、macOS 和 Linux 上使用喜爱的开发工具。 部署到云或本地。 在 .NET Core 上运行。 ASP.NET Core 是对 ASP

    2024年02月06日
    浏览(66)
  • ASP.NET Core 配置系列一

    A S P . N E T   C o r e   配 置 主 要 通 过 这 3 个 文 件 设 置 : 1   项 目 文 件 也 叫 . c s p r o j   文 件 2   P r o g r a m . c s 3   a p p s e t t i n g s . j s o n 这 些 配 置 告 诉 A S P . N E T   C o r e   应 用 程 序 基 于 用 户 的 交 互 是 如 何 工 作 的, 在 本 节 中 我 们 理 解 A S P .

    2024年02月03日
    浏览(108)
  • ASP.NET Core 依赖注入系列一

    什么是ASP.NET Core 依赖注入? 依赖注入也称DI是一项技术用来实现对象松耦合以至于应用程序更容易维护,ASP.NET Core通过控制器的构造函数自动注入依赖的对象,我们创建ASP.NET Core MVC应用程序演示依赖注入特性是如何工作, 在这节中我们讲解该特性 1 例子 我们创建一个ASP.NET C

    2024年02月11日
    浏览(53)
  • ASP.NET Core SignalR 系列(二)- 中心(服务端)

    本章将和大家分享 ASP.NET Core SignalR 中的中心(服务端)。 本文大部分内容摘自微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/signalr/hubs?view=aspnetcore-7.0 废话不多说,我们直接来看一个Demo,Demo的目录结构如下所示: 本Demo的Web项目为ASP.NET Core Web 应用程序( 目标框架为.NET 7.0

    2024年02月13日
    浏览(53)
  • Asp .Net Core 系列: 集成 CORS跨域配置

    CORS,全称是“跨源资源共享”(Cross-Origin Resource Sharing),是一种Web应用程序的安全机制,用于控制不同源的资源之间的交互。 在Web应用程序中,CORS定义了一种机制,通过该机制,浏览器能够限制哪些外部网页可以访问来自不同源的资源。源由协议、域名和端口组成。当一

    2024年01月24日
    浏览(88)
  • ASP.NET Core SignalR 系列(四)- 中心筛选器

    本章将和大家分享 ASP.NET Core SignalR 中的中心筛选器。 本文大部分内容摘自微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/signalr/hub-filters?view=aspnetcore-7.0 废话不多说,下面我们直接进入本章主题。 中心筛选器: 在 ASP.NET Core 5.0 或更高版本中可用。 允许在客户端调用中心方法之

    2024年02月16日
    浏览(46)
  • 你所不知道的ASP.NET Core进阶系列(三)

    一年多没更新博客,上一次写此系列还是四年前,虽迟但到,没有承诺,主打随性,所以不存在断更,催更,哈哈,上一篇我们细究从请求到绑定详细原理,本篇则是探讨模型绑定细节,当一个问题产生到最终解决时,回过头我们整体分析其产生背景以及设计思路才能有所获

    2024年02月05日
    浏览(93)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包