首页 > 其他分享 >不会使用 EF Core 的 Code First 模式?来看看这篇文章,手把手地教你

不会使用 EF Core 的 Code First 模式?来看看这篇文章,手把手地教你

时间:2023-12-27 17:45:14浏览次数:32  
标签:Core 实体类 set get builder EF Code public First

EF Core Code First 是什么

Code First 是 Entity Framework Core (简称 EF Core) 的一种开发模式,它允许开发人员使用纯粹的代码来定义数据模型,通过它,可以极大地提高开发效率:

  1. 使用 Code First 开发模式,你可以专注于定义领域模型和业务逻辑,而无需关注数据库的细节,能够更快地构建应用程序
  2. Code First 是真正地面向对象的方式来定义数据模型,包括实体类、关系、继承等,这些都让数据模型的设计更加直观和易于理解
  3. Code First 支持多种数据库,包括 SQL Server、MySQL、PostgreSQL 等,你可以在不同的数据库之间进行切换而无需修改代码
  4. Code First 提供了数据库迁移工具,可以根据模型变化自动创建、更新和维护数据库模式,数据库的版本控制和迁移变得更加容易,也减少了手动编写 SQL 脚本的工作量

Step By Step 使用 Code First 步骤

  1. 创建一个 asp.net core Console 项目
  2. 从 Nuget 安装以下包

    Microsoft.EntityFrameworkCore.SqlServer
    Microsoft.EntityFrameworkCore.Tools

  3. 创建实体类 Article 和 Comment
    public class Article
    {
    	/// <summary>
    	/// 主键
    	/// </summary>
    	public long Id { get; set; }
    
    	/// <summary>
    	/// 标题
    	/// </summary>
    	public string Title { get; set; }
    
    	/// <summary>
    	/// 内容
    	/// </summary>
    	public string Content { get; set; }
    
    	/// <summary>
    	/// 此文章的若干条评论
    	/// </summary>
    	public List<Comment> Comments { get; set; } = new List<Comment>(); 
    }
    
    public class Comment
    {
    	public long Id { get; set; }
    	public Article Article { get; set; }
    	public long ArticleId { get; set; }
    	public string Message { get; set; }
    }
    
  4. 创建实现了IEntityTypeConfiguration接口的实体类的配置类,用于配置实体类和数据库表的对应关系
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata.Builders;
    
    // IEntityTypeConfiguration的泛型参数类指定这个类要对实体类 Article 进行配置
    class ArticleConfig : IEntityTypeConfiguration<Article>
    {
    	// 使用Fluent API的方式对实体类进行配置
    	// 也可以在实体类中使用 Data Annotation 进行配置,但那样耦合太深,不推荐使用
    	public void Configure(EntityTypeBuilder<Article> builder)
    	{
    		
    		// 表示这个实体类对应数据库中名字为T_Articles的表
    		builder.ToTable("T_Articles");
    		builder.Property(p => p.Content).IsRequired().IsUnicode();
    		builder.Property(p => p.Title).IsRequired().IsUnicode()
    			.HasMaxLength(255);
    	}
    }
    
    class CommentConfig : IEntityTypeConfiguration<Comment>
    {
    	public void Configure(EntityTypeBuilder<Comment> builder)
    	{
    		builder.ToTable("T_Comments");
    
    		// 一条评论对应一篇文章,一篇文章有多条评论
    		builder.HasOne<Article>(c =>c.Article)
    			.WithMany(a => a.Comments)
    			.IsRequired()
    			.HasForeignKey(c => c.ArticleId);
    		builder.Property(p=>p.Message).IsRequired().IsUnicode();
    	}
    }
    
  5. 创建一个继承自DbContext类的TestDbContext类(上下文类)
    using Microsoft.EntityFrameworkCore;
    
    class TestDbContext: DbContext
    {
    	public DbSet<Article> Articles { get; set; }
    	public DbSet<Comment> Comments { get; set; }
    
    	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    	{
    		string connStr = "Server=(localdb)\\mssqllocaldb;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true";
    		optionsBuilder.UseSqlServer(connStr);
    	}
    
    	protected override void OnModelCreating(ModelBuilder modelBuilder)
    	{
    		base.OnModelCreating(modelBuilder);
    
    		// 表示加载当前程序集中所有实现了IEntityTypeConfiguration接口的类
    		modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
    	}
    }	
    
  6. 迁移(根据实体类生成数据库表)
    1. 打开 菜单 - 工具 - 程序包管理器控制台
    2. 默认项目下拉框选择目标项目【可选,如果解决方案有多个项目】
    3. 执行如下命令:

      Add-Migration InitialCreate 【InitialCreate 名字可随意取,有意义就好】
      说明:Add-Migration命令会自动在项目的Migrations文件夹中生成C#代码

    4. 执行命令

      Update-database
      说明:编译并且执行数据库迁移代码

    5. 查看 sql server 数据库是否执行成功
    6. 如果添加或修改字段,重复执行3~4步命令
  7. 至此,EF Core 的 Code First 过程已经完成,接着就可以对数据进行增删改查等操作

扩展 - Fluent API 基本语法例子

  1. 视图与实体类映射
    modelBuilder.Entity<Blog>().ToView("blogsView");
    
  2. 排除属性映射
    modelBuilder.Entity<Blog>().Ignore(b => b. Name2);
    
  3. 数据库表列名
    modelBuilder.Entity<Blog>().Property(b =>b.BlogId).HasColumnName("blog_id");
    
  4. 列数据类型
    builder.Property(e => e.Title) .HasColumnType("varchar(200)")
    
  5. 主键
    modelBuilder.Entity<Student>().HasKey(c => c.Number);
    
  6. 索引
    modelBuilder.Entity<Blog>().HasIndex(b => b.Url);
    
    // 复合索引
    modelBuilder.Entity<Person>().HasIndex(p => new { p.FirstName, p.LastName });
    
  7. 多对多
    builder.HasMany<Teacher>(c => c.Teachers).WithMany(t => t.Students)
    	.UsingEntity(j => j.ToTable("T_Students_Teachers"));
    
  8. 1对多
    builder.HasOne<Article>(c =>c.Article)
    	.WithMany(a => a.Comments)
    	.IsRequired()
    	.HasForeignKey(c => c.ArticleId);
    
  9. 1对1
    builder.HasOne<Delivery>(c => c.Delivery).WithOne(d => d.Order)
    	.HasForeignKey<Delivery>(d => d.OrderId);

标签:Core,实体类,set,get,builder,EF,Code,public,First
From: https://www.cnblogs.com/JackyGz/p/17931042.html

相关文章

  • Taurus .Net Core 微服务开源框架:Admin 插件【4-7】 - 配置管理-Mvc【Plugin-Metric
    前言:继上篇:Taurus.NetCore微服务开源框架:Admin插件【4-6】-配置管理-Mvc【Plugin-Doc接口测试及文档】本篇继续介绍下一个内容:系统配置节点:Mvc- Plugin-Metric接口调用次数统计:配置界面如下:1、Metric.IsEnable:配置当前接口统计插件是否可用打开开关时,可以通......
  • Leetcode每日一题
    目录202312/2512/2612/27202312月往前的应该就不会补题解了,大概有时间会往前一直补到12/1的题解12/251276.不浪费原料的汉堡制作方案题目分析:数学题,解二元一次方程即可具体过程有$$\left{\begin{array}{c}4x+2y=tomatoSlices\x+y=cheeseSlices\end{array}\right.$$......
  • swagger报错Unable to render this definition
    问题描述:访问swagger时,报错endofthestreamoradocumentseparatorisexpected,UnabletorenderthisdefinitionTheprovideddefinitiondoesnotspecifyavalidversionfield.PleaseindicateavalidSwaggerorOpenAPIversionfield.Supportedversionfields......
  • verilog代码中为什么要加`default_nettype none
    在Verilog中,default_nettypenone语句用于禁止隐式声明信号类型,这样可以增强代码的可读性和可维护性。Verilog语言允许在使用信号之前不显式声明信号类型,而是根据信号名的前缀来推断信号的类型(比如wire或reg)。然而,这种隐式声明的方式可能会导致一些问题,特别是在大型项目或多人协......
  • 韩国国民搜索 NAVER:为 AI 平台引入存储方案 JuiceFS
    NAVER是一家多元化的互联网公司,拥有韩国最大的搜索引擎并在人工智能、自动驾驶等高科技领域积极投入。在搭建AI平台时,NAVER评估了公有云平台的存储产品、Alluxio以及高性能专用存储产品等多种选项后,最终决定采用JuiceFS。通过使用JuiceFS,NAVER成功地将内部存储资源升级为......
  • python代码pycharm 中可以运行 vscode无法运行
    问题:pycharm中可以运行,切到vscode中时无法运行,都是路径无法读取到导致模块无法加载。分析:主要原因有可能是VSCode默认使用项目文件夹根目录作为工作目录(cwd),这会使得子文件夹中的程序无法使用相对路径。vscode中设置一下:文件=>首选项=>设置中搜索ExecuteinFileDir,......
  • EFK(更新中)
    nginx日志配置log_formataccess_json'{"@timestamp":"$time_iso8601",'    '"host":"$server_addr",'    '"clientip":"$remote_addr",'    '"size&qu......
  • map|动态规划|单调栈|LeetCode975:奇偶跳
    作者推荐【贪心算法】【中位贪心】.执行操作使频率分数最大涉及知识点单调栈动态规划map题目给定一个整数数组A,你可以从某一起始索引出发,跳跃一定次数。在你跳跃的过程中,第1、3、5…次跳跃称为奇数跳跃,而第2、4、6…次跳跃称为偶数跳跃。你可以按以下方式从索引i向后跳转......
  • 【动态规划】leetcode 不同路径问题
    题目名称:63.不同路径II链接:https://leetcode.cn/problems/unique-paths-ii/description/题目内容:一个机器人位于一个 mxn 网格的左上角(起始点在下图中标记为“Start”)。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。......
  • 磁盘调度算法、虚拟内存、抖动(颠簸)、堆栈访问速度、内存分配、内存交换、编码(ASCII、U
    常见的几种磁盘调度算法:读写一个磁盘块的时间的影响因素有:......