博客
关于我
.net core 中使用 EFcore做ORM
阅读量:268 次
发布时间:2019-03-01

本文共 10173 字,大约阅读时间需要 33 分钟。

文章目录


1.准备

  1. 安装mysql数据库

  2. 如果使用EF core,查阅efcore 官方文档

  3. EF core 的各种提供商

使用 Mysql的源码源码的版本要对应,不然容易报错


使用mysql 数据库进行操作,只要装两个包就行

在这里插入图片描述


2.安装相应的 nuge 包

Install-Package MySql.Data.EntityFrameworkCore -Version 8.0.22

EF core 的 PMC 工具

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

验证是否安装成功

Get-Help about_EntityFrameworkCore
_/\__               ---==/    \\         ___  ___   |.    \|\        | __|| __|  |  )   \\\        | _| | _|   \_/ |  //|\\        |___||_|       /   \\\/\\TOPIC    about_EntityFrameworkCoreSHORT DESCRIPTION    Provides information about the Entity Framework Core Package Manager Console Tools.

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 AddBlogCreatedTimestampUpdate-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
Classrooms { get; set; } //Classrooms 是表名字 public DbSet
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
Students { get; set; } = new List
(); //导航属性,实际的数据库中并没有 } 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
().HasOne(x => x.Province).WithMany(x => x.Cities).HasForeignKey(x => x.ProvinceId); //第二种 modelBuilder.Entity
<实体主体>
modelBuilder.Entity
().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
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
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
options) : base(options) { } public DbSet
Courses { get; set; } public DbSet
Enrollments { get; set; } public DbSet
Students { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity
().ToTable("TableCourse"); //指定表的名字 modelBuilder.Entity
().ToTable("Enrollment"); modelBuilder.Entity
().ToTable("Student"); //添加种子数据 modelBuilder.Entity
().HasData( new Student { ID=1, FirstMidName = "Carson", LastName = "Alexander", EnrollmentDate = DateTime.Parse("2005-09-01") } ); } }

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

services.AddDbContext
(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
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
().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
options):base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder){ //使用x.CityId,x.CompanyId生成 cityCompany的联合主键 //执行数据库迁移 modelBuilder.Entity
().HasKey(x => new{ x.CityId,x.CompanyId}); //配置多对多 ,就是两个一对多,可以不写 modelBuilder.Entity
().HasOne(x => x.City).WithMany(x=> x.CityCompany).HasForeignKey(x=>x.CityId); modelBuilder.Entity
().HasOne(x => x.Company).WithMany(x=> x.CityCompany).HasForeignKey(x=>x.CompanyId); } public DbSet
Cities { get; set; } public DbSet
cityCompanies { get;set;} } public class City { public City() { CityCompany = new List
(); } 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 { get;set;} } public class Company { public Company() { CityCompany = new List
(); } public int Id { get;set;} public string Name { get;set;} public DateTime EstablishDate { get;set;} public string LegalPerson { get;set;} //多对多映射 public List
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]

[2]

转载地址:http://nywl.baihongyu.com/

你可能感兴趣的文章