.net core 中使用 EFcore做ORM

it2025-07-30  8

文章目录

1.准备2.安装相应的 nuge 包3.软件包管理控制台3.1迁移的过程3.2其他的 EF Core 命令行工具 4.一个简单的应用实例4.1建表4.2 增删改查操作 5.指定表之间的关系6.一个复杂点的例子7.忽略某一个属性8.多对多参考文献:


1.准备

安装mysql数据库 2 .在msql数据库中使用 efcore,可以查阅msql官方文档https://www.nuget.org/packages/MySql.Data.EntityFrameworkCore/如果使用EF core,查阅efcore 官方文档https://docs.microsoft.com/zh-cn/ef/core/get-started/?tabs=visual-studio

使用 Mysql的源码https://gitee.com/rush_peng/netcore-31---medium-ef-core.git源码的版本要对应,不然容易报错

2.安装相应的 nuge 包

Install-Package MySql.Data.EntityFrameworkCore -Version 8.0.22

EF core 的 PMC 工具

Install-Package Microsoft.EntityFrameworkCore.Tools Add-Migration InitialCreate #命令为迁移搭建基架 Update-Database #命令创建数据库并向其应用新的迁移

验证是否安装成功

Get-Help about_EntityFrameworkCore _/\__ ---==/ \\ ___ ___ |. \|\ | __|| __| | ) \\\ | _| | _| \_/ | //|\\ |___||_| / \\\/\\ TOPIC about_EntityFrameworkCore SHORT DESCRIPTION Provides information about the Entity Framework Core Package Manager Console Tools. <A list of available commands follows, omitted here.>

3.软件包管理控制台

在实际项目中,数据模型随着功能的实现而变化:添加和删除新的实体或属性,并且需要相应地更改数据库架构,使其与应用程序保持同步。 EF Core 中的迁移功能能够以递增方式更新数据库架构,使其与应用程序的数据模型保持同步,同时保留数据库中的现有数据。


3.1迁移的过程

1.比如你刚开始创建了一个程序

public class Blog { public int Id { get; set; } public string Name { get; set; } }

2.这个时候,你需要做一个迁移:(数据库字段从无到有)

Add-Migration InitialCreate

EF Core 将在项目中创建一个名为“Migrations”的目录,并生成一些文件。 最好检查 EF Core 生成的内容,并在可能的情况下修改它,但现在我们跳过此操作。 initialCreate 是自己给此次迁移起的一个名字。

3.执行迁移

Update-Database

4.过了几天,你又修改了模型

public class Blog { public int Id { get; set; } public string Name { get; set; } public DateTime CreatedTimestamp { get; set; } }

5.执行迁移命令

Add-Migration AddBlogCreatedTimestamp Update-Database

3.2其他的 EF Core 命令行工具

若要显示有关命令的帮助信息,请使用 PowerShell Get-Help 命令。

Add-Migration : 添加新的迁移Drop-Database : 删除数据库Remove-Migration:删除上一次迁移 (回滚对迁移) 所做的代码更改。Update-Database:将数据库更新到上次迁移或指定迁移。

4.一个简单的应用实例

一个学校的数据库表,一个班级对应多个学生,一个学生,对应一个班级

4.1建表

DbsetClassrooms 一定要加 pubulic

public class School:DbContext { public DbSet<Classroom> Classrooms { get; set; } //Classrooms 是表名字 public DbSet<Student> Students { get; set; } //Students 是表名字 protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseMySQL ("server=localhost;database=studentmessage;user=root;password=123456"); //连接本地数据库 // options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=test02;Trusted_Connection=True;MultipleActiveResultSets=true"); } public class Classroom { public int ClassroomId { get; set; } //带有id 的默认就是主键 public string address { get; set; } public List<Student> Students { get; set; } = new List<Student>(); //导航属性,实际的数据库中并没有 } public class Student { public int StudentId { get; set; } public string Gender { get; set; } public int ClassroomId { get; set; } public Classroom classroom { get; set; } //导航属性,实际的数据库中并没有 }

4.2 增删改查操作

using (var db = new SchoolDbContext()) { //create Console.WriteLine("添加一个班级"); db.Add(new Classroom { address = "教学楼一楼", ClassroomId = 4 }); //注意 相同的 add 命令,只能执行一次。 db.Add(new Classroom { address = "教学楼二楼", ClassroomId = 3 }); db.SaveChanges(); //read Console.WriteLine("读一个班级的信息"); var classroomdb01 = db.Classrooms .OrderBy(b => b.ClassroomId) .First(); Console.WriteLine(classroomdb01.ClassroomId); //update //更新的是上边选出来的人的 classroomdb01.address = "教学楼楼顶"; db.SaveChanges(); classroomdb01.Students.Add( new Student { Name = "张三", Gender = "男", StudentId = 1, ClassroomId = 1 } ); db.SaveChanges(); //delete db.Remove(classroomdb01); db.SaveChanges(); }

5.指定表之间的关系

参考文献1对这块写的不错,可以看看 目前 EF 不能直接实现多对多的关系,需要用个中间类做调整。两边的导航属性是数组,中间类的两个导航属性是实体(可以看看下边 6复杂点的例子)

声明一个主体实体(主表)与依赖实体(从表)指定modelBuilder.Entity,T是依赖实体或者主体实体HasOne 或 HasMany 标识依赖实体中(即正在配置的)的导航属性WithOne 或 WithMany 来标识反向实体的导航属性HasForeignKey中标识外键(从表)

看下边的例子:

配置多对一的关系,可以使用两种写法,这里City是依赖实体(从表),其中包含外键ProvinceId,Province是主体实体

//第一种 modelBuilder.Entity<依赖主体> modelBuilder.Entity<City>().HasOne(x => x.Province). WithMany(x => x.Cities).HasForeignKey(x => x.ProvinceId); //第二种 modelBuilder.Entity<实体主体> modelBuilder.Entity<Province>().HasMany(x => x.Cities). WithOne(x => x.Province).HasForeignKey(x => x.ProvinceId);

6.一个复杂点的例子

创建数据库上下文上下文依赖注入使用添加种子数据创建表的时候指定表明

前期准备,建立学生 . 课程. 选课 三个类!

public class Course { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } public enum Grade { A, B, C, D, F } public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public Course Course { get; set; } public Student Student { get; set; } }

1.创建数据库上下文

public class SchoolContext : DbContext { public SchoolContext(DbContextOptions<SchoolContext> options) : base(options) { } public DbSet<Course> Courses { get; set; } public DbSet<Enrollment> Enrollments { get; set; } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Course>().ToTable("TableCourse"); //指定表的名字 modelBuilder.Entity<Enrollment>().ToTable("Enrollment"); modelBuilder.Entity<Student>().ToTable("Student"); //添加种子数据 modelBuilder.Entity<Student>().HasData( new Student {ID=1, FirstMidName = "Carson", LastName = "Alexander", EnrollmentDate = DateTime.Parse("2005-09-01") } ); } }

2.依赖注入使用上下文:

services.AddDbContext<SchoolContext>(options => options.UseMySQL(Configuration.GetConnectionString("DefaultConnection"))); // GetConnectionString 按 F12 进去,他就是找一个名叫 ConnectionStrings 的字符串

3.在appsettings.json 文件里添加链接字符串

"ConnectionStrings": { "mysqlConnection": "server=localhost;database=progress_track;user=root;password=123456", "aliyunMySql": "server=rm.aliyuncs.com;port=3306;database=mysql;user=zhao;password=xxxxxxx", "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=progress_track;Trusted_Connection=True;MultipleActiveResultSets=true" },

4.在需要用到数据库的地方,直接依赖注入引用就可以 注意一下异步的用法

public class StudentController : ControllerBase { private readonly SchoolContext schoolContext; private int dex = 2; public StudentController(SchoolContext schoolContext) { this.schoolContext = schoolContext; } [HttpGet("add")] public async Task<int> AddCreateAsync() //只要里面有异步的思想,就要使用 Task { var students = new Student[] { new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")}, new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")}, new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")}, new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")}, new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")} }; foreach (var student in students) { student.ID = ++dex; schoolContext.Students.Add(student); } var resut = await schoolContext.SaveChangesAsync(); return resut; } }

7.忽略某一个属性

如何在 Entity 中有,但是不在数据库中建立相应的字段

modelBuilder.Entity<Company>().Ignore(x=>x.testIgnore)

8.多对多

以city和company为例,一个city会有多个company,一个company在多个city都有多个分company

using System; using Microsoft.EntityFrameworkCore; namespace ASPNetEFFCore.Models { public class MyContext:DbContext { public MyContext(DbContextOptions<MyContext> options):base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder){ //使用x.CityId,x.CompanyId生成 cityCompany的联合主键 //执行数据库迁移 modelBuilder.Entity<CityCompany>().HasKey(x => new{x.CityId,x.CompanyId}); //配置多对多 ,就是两个一对多,可以不写 modelBuilder.Entity<CityCompany>().HasOne(x => x.City).WithMany(x=> x.CityCompany).HasForeignKey(x=>x.CityId); modelBuilder.Entity<CityCompany>().HasOne(x => x.Company).WithMany(x=> x.CityCompany).HasForeignKey(x=>x.CompanyId); } public DbSet<City> Cities { get; set; } public DbSet<CityCompany> cityCompanies {get;set;} } public class City { public City() { CityCompany = new List<CityCompany>(); } public int Id { get; set; } public string Name { get; set; } public string AreaCode { get; set; } public int ProvinceId { get; set; } public Province Province { get; set; } //多对多映射 public List<CityCompany> CityCompany {get;set;} } public class Company { public Company() { CityCompany = new List<CityCompany>(); } public int Id {get;set;} public string Name {get;set;} public DateTime EstablishDate {get;set;} public string LegalPerson {get;set;} //多对多映射 public List<CityCompany> CityCompany {get;set;} } //多对多中间model public class CityCompany { public int CityId {get;set;} public City City{get;set;} public int CompanyId {get;set;} public Company Company {get;set;} } }

参考文献:

[1]https://blog.csdn.net/weixin_41372626/article/details/104740176 [2]微软官方网站

最新回复(0)