CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

先来一张祖师爷镇楼。
CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

哎呀呀! 搞错了搞错了,当然应该是这个头发多的…

CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

在之前的时候博主介绍过关于C#中的ORM框架,博主本人也使用过Java的ORM框架MyBatis,但是我还是觉得C#的ORM框架丝滑。

回到正题,我们来开始我们本次的内容

1. 搭建一个演示Demo

创建三个类库Demo.MainForm(Window窗体)、Demo.Domain(类库)、Demo.Data(类库)

1.1. 在Demo.Domain中我们创建三个类

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

namespace Demo.Domain
{
    public class Classroom
    {
        public Classroom()
        {

        }

        public int Id
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public Teacher MathTeacher
        {
            get;
            set;
        }

        public List<Student> ListStu
        {
            get;
            set;
        }
    }
}


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

namespace Demo.Domain
{
    public class Student
    {
        public Student()
        { 
        
        }


        public int Id
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public string AddressCity
        {
            get;
            set;
        }

        public int Age
        {
            get;
            set;
        }

    }
}

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

namespace Demo.Domain
{
    public class Teacher
    {
        public Teacher()
        { 
        
        }

        public int Id
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public int Age
        {
            get;
            set;
        }

    }
}


1.2. 在Demo.Data中使用NuGet引入EFCore

在NuGet中引入:Microsoft.EntityFrameworkCore.Sqlite
CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

安装这个类库,会自动安装如下内容:

Demo.Data

正在安装:

Microsoft.Data.Sqlite.Core.5.0.7
Microsoft.DotNet.PlatformAbstractions.3.1.6
Microsoft.EntityFrameworkCore.5.0.7
Microsoft.EntityFrameworkCore.Abstractions.5.0.7
Microsoft.EntityFrameworkCore.Analyzers.5.0.7
Microsoft.EntityFrameworkCore.Relational.5.0.7
Microsoft.EntityFrameworkCore.Sqlite.5.0.7
Microsoft.EntityFrameworkCore.Sqlite.Core.5.0.7
Microsoft.Extensions.Caching.Abstractions.5.0.0
Microsoft.Extensions.Caching.Memory.5.0.0
Microsoft.Extensions.Configuration.Abstractions.5.0.0
Microsoft.Extensions.DependencyInjection.5.0.1
Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0
Microsoft.Extensions.DependencyModel.5.0.0
Microsoft.Extensions.Logging.5.0.0
Microsoft.Extensions.Logging.Abstractions.5.0.0
Microsoft.Extensions.Options.5.0.0
Microsoft.Extensions.Primitives.5.0.0
SQLitePCLRaw.bundle_e_sqlite3.2.0.4
SQLitePCLRaw.core.2.0.4
SQLitePCLRaw.lib.e_sqlite3.2.0.4
SQLitePCLRaw.provider.dynamic_cdecl.2.0.4
System.Collections.Immutable.5.0.0
System.ComponentModel.Annotations.5.0.0
System.Diagnostics.DiagnosticSource.5.0.1
System.Memory.4.5.3

引入完成之后,会产生如下依赖包信息:
CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

1.3. 在Demo.Data中增加两个NuGet引用

Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.Design

以下内容如果需要展开,可以借鉴:

https://blog.csdn.net/xingkongtianyuzhao/article/details/104228019

1.4. 打开包管理器

PM> get-help entityframework

                     _/\__
               ---==/    \\
         ___  ___   |.    \|\
        | __|| __|  |  )   \\\
        | _| | _|   \_/ |  //|\\
        |___||_|       /   \\\/\\

TOPIC
    about_EntityFrameworkCore

SHORT DESCRIPTION
    Provides information about the Entity Framework Core Package Manager Console Tools.

LONG DESCRIPTION
    This topic describes the Entity Framework Core Package Manager Console Tools. See https:/5/docs.efproject.net for
    information on Entity Framework Core.

    The following Entity Framework Core commands are available.

        Cmdlet                      Description
        --------------------------  ---------------------------------------------------
        Add-Migration               Adds a new migration.

        Drop-Database               Drops the database.

        Get-DbContext               Lists and gets information about available DbContext types.

        Get-Migration               Lists available migrations.

        Remove-Migration            Removes the last migration.

        Scaffold-DbContext          Scaffolds a DbContext and entity types for a database.

        Script-DbContext            Generates a SQL script from the DbContext. Bypasses any migrations.

        Script-Migration            Generates a SQL script from migrations.

        Update-Database             Updates the database to a specified migration.

SEE ALSO
    Add-Migration
    Drop-Database
    Get-DbContext
    Get-Migration
    Remove-Migration
    Scaffold-DbContext
    Script-DbContext
    Script-Migration
    Update-Database

PM>  add-migration Initial
Build started...
Build succeeded.
Your startup project 'Demo.MainForm' doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work. Ensure your startup project is correct, install the package, and try again.
PM>  add-migration Initial
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> 

CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

1.5. 生成数据库初始化语句

PM> script-migration
Build started...
Build succeeded.
CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" (
    "MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY,
    "ProductVersion" TEXT NOT NULL
);

BEGIN TRANSACTION;

CREATE TABLE "Teachers" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Teachers" PRIMARY KEY AUTOINCREMENT,
    "Name" TEXT NULL,
    "Age" INTEGER NOT NULL
);

CREATE TABLE "Classrooms" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Classrooms" PRIMARY KEY AUTOINCREMENT,
    "Name" TEXT NULL,
    "MathTeacherId" INTEGER NULL,
    CONSTRAINT "FK_Classrooms_Teachers_MathTeacherId" FOREIGN KEY ("MathTeacherId") REFERENCES "Teachers" ("Id") ON DELETE RESTRICT
);

CREATE TABLE "Students" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Students" PRIMARY KEY AUTOINCREMENT,
    "Name" TEXT NULL,
    "AddressCity" TEXT NULL,
    "Age" INTEGER NOT NULL,
    "ClassroomId" INTEGER NULL,
    CONSTRAINT "FK_Students_Classrooms_ClassroomId" FOREIGN KEY ("ClassroomId") REFERENCES "Classrooms" ("Id") ON DELETE RESTRICT
);

CREATE INDEX "IX_Classrooms_MathTeacherId" ON "Classrooms" ("MathTeacherId");

CREATE INDEX "IX_Students_ClassroomId" ON "Students" ("ClassroomId");

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20210704071701_Initial', '5.0.7');

COMMIT;

CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

1.6. 修改表字段设计

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

namespace Demo.Domain
{
    public class Student
    {
        public Student()
        { 
        
        }

        public int Id
        {
            get;
            set;
        }

        [Required]
        [MaxLength(50)]
        public string Name
        {
            get;
            set;
        }

        [Required, MaxLength(50)]
        public string AddressCity
        {
            get;
            set;
        }

        public int Age
        {
            get;
            set;
        }

    }
}

生成更新

PM> Add-Migration ChangeSomeProperties
Build started...
Build succeeded.
An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy.
To undo this action, use Remove-Migration.

CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

PM> update-database
Build started...
Build succeeded.
Applying migration '20210704073825_ChangeSomeProperties'.
Done.

CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

2. 简单的增删改查

2.1 增加->Insert

using var context = new DemoContext();

{
    Teacher teacher = new Teacher()
    {
        Name = "高子文",
        Age = 38
    };
    context.Teachers.Add(teacher);

    Classroom classroom = new Classroom()
    {
        Name = "三年八班",
        MathTeacher = teacher
    };

    context.Classrooms.Add(classroom);

    context.SaveChanges();
}

CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

批量增加

 //批量增加
{ 
    var classroom=context.Classrooms.Single(a=>a.Name=="三年八班");
    Student student_SYF = new Student()
    {
        Name = "石延枫",
        AddressCity = "上海",
        Age = 18,
        StudyClassroom = classroom
    };
    Student student_LFL = new Student()
    {
        Name = "蓝菲琳",
        AddressCity = "上海",
        Age = 18,
        StudyClassroom = classroom
    };
    Student student_TS = new Student()
    {
        Name = "唐宋",
        AddressCity = "上海",
        Age = 18,
        StudyClassroom = classroom
    };
    //批量添加
    context.AddRange(student_SYF, student_LFL, student_TS);
    //context.Students.AddRange(student_SYF, student_LFL, student_TS);
    //context.Students.AddRange(new List<Student>() { student_SYF, student_LFL, student_TS });
    context.SaveChanges();
}

2.2 查询->Search

public class DemoContext:DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseLoggerFactory(ConsoleLoggerFactory)
            .EnableSensitiveDataLogging()
            .UseSqlite(@"Data Source=C:\Users\xiaocai\Desktop\Code\EFCoreDemo\bin\net5.0\DemoDBSqlite.db");
    }
}


delete from Classrooms;

delete from Students;

delete from Teachers;

using Demo.Data;
using Demo.Domain;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo.App
{
    class Program
    {
        static void Main(string[] args)
        {
            using var context = new DemoContext();

            //增
            {

                Teacher teacher = new Teacher()
                {
                    Name = "高子文",
                    Age = 38
                };
                context.Teachers.Add(teacher);

                Classroom classroom = new Classroom()
                {
                    Name = "三年八班",
                    MathTeacher = teacher
                };

                context.Classrooms.Add(classroom);

                context.SaveChanges();
            }

            //查
            {
                var classroom = context.Classrooms.Single(a => a.Name == "三年八班");

                Student student_SYF = new Student()
                {
                    Name = "石延枫",
                    AddressCity = "上海",
                    Age = 18,
                    StudyClassroom = classroom
                };

                Student student_LFL = new Student()
                {
                    Name = "蓝菲琳",
                    AddressCity = "上海",
                    Age = 18,
                    StudyClassroom = classroom
                };

                Student student_TS = new Student()
                {
                    Name = "唐宋",
                    AddressCity = "上海",
                    Age = 18,
                    StudyClassroom = classroom
                };

                Student student_TB = new Student()
                {
                    Name = "唐宝",
                    AddressCity = "上海",
                    Age = 20,
                    StudyClassroom = classroom
                };

                //批量添加
                context.AddRange(student_SYF, student_LFL, student_TS, student_TB);

                //context.Students.AddRange(student_SYF, student_LFL, student_TS);
                //context.Students.AddRange(new List<Student>() { student_SYF, student_LFL, student_TS });


                context.SaveChanges();
            }

            //查询
            {

                //查询全部
                var students= context.Students.ToList();

                //查询单个
                var classroom = context.Classrooms.Single(a => a.Name == "三年八班");

                //查询条件
                var students_Search = context.Students.Where(a=>a.Name.StartsWith("唐")).ToList();

                var teacher_LinqSearch = (from lg in context.Students
                                          where lg.Name.StartsWith("唐")
                                          select lg).ToList();

                int targetAge = 18;
                var students_AgeSearch = context.Students.Where(a => a.Age == targetAge).ToList();


            }

            Console.ReadKey();
        }
    }
}


最终输出如下:

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (11ms) [Parameters=[@p0='38' (DbType = String), @p1='高子文' (Size = 3)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Teachers" ("Age", "Name")
      VALUES (@p0, @p1);
      SELECT "Id"
      FROM "Teachers"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@p2='10' (Nullable = true) (DbType = String), @p3='三年八班' (Size = 4)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Classrooms" ("MathTeacherId", "Name")
      VALUES (@p2, @p3);
      SELECT "Id"
      FROM "Classrooms"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "c"."Id", "c"."MathTeacherId", "c"."Name"
      FROM "Classrooms" AS "c"
      WHERE "c"."Name" = '三年八班'
      LIMIT 2
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (2ms) [Parameters=[@p0='上海' (Nullable = false) (Size = 2), @p1='18' (DbType = String), @p2=' 蓝菲琳' (Nullable = false) (Size = 3), @p3='10' (Nullable = true) (DbType = String)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Students" ("AddressCity", "Age", "Name", "StudyClassroomId")
      VALUES (@p0, @p1, @p2, @p3);
      SELECT "Id"
      FROM "Students"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@p0='上海' (Nullable = false) (Size = 2), @p1='18' (DbType = String), @p2=' 石延枫' (Nullable = false) (Size = 3), @p3='10' (Nullable = true) (DbType = String)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Students" ("AddressCity", "Age", "Name", "StudyClassroomId")
      VALUES (@p0, @p1, @p2, @p3);
      SELECT "Id"
      FROM "Students"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@p0='上海' (Nullable = false) (Size = 2), @p1='18' (DbType = String), @p2=' 唐宋' (Nullable = false) (Size = 2), @p3='10' (Nullable = true) (DbType = String)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Students" ("AddressCity", "Age", "Name", "StudyClassroomId")
      VALUES (@p0, @p1, @p2, @p3);
      SELECT "Id"
      FROM "Students"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@p0='上海' (Nullable = false) (Size = 2), @p1='20' (DbType = String), @p2=' 唐宝' (Nullable = false) (Size = 2), @p3='10' (Nullable = true) (DbType = String)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Students" ("AddressCity", "Age", "Name", "StudyClassroomId")
      VALUES (@p0, @p1, @p2, @p3);
      SELECT "Id"
      FROM "Students"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "c"."Id", "c"."MathTeacherId", "c"."Name"
      FROM "Classrooms" AS "c"
      WHERE "c"."Name" = '三年八班'
      LIMIT 2
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Name" LIKE '唐%'
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Name" LIKE '唐%'
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@__targetAge_0='18' (DbType = String)], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Age" = @__targetAge_0
//查询
{
    //查询全部
    var students= context.Students.ToList();

    //查询单个
    var classroom = context.Classrooms.Single(a => a.Name == "三年八班");

    //查询条件
    var students_Search = context.Students.Where(a=>a.Name.StartsWith("唐")).ToList();
    var teacher_LinqSearch = (from lg in context.Students
                              where lg.Name.StartsWith("唐")
                              select lg).ToList();

    int targetAge = 18;
    var students_AgeSearch = context.Students.Where(a => a.Age == targetAge).ToList();
    //查询条件
    var students_Search_1 = context.Students.Where(a => a.Name.StartsWith("唐")).ToList();
    //查询条件
    var students_Search_2 = context.Students.Where(a => a.Name.Contains("唐")).ToList();
    //查询条件
    var students_Search_3 = context.Students
        .Where(a =>
            EF.Functions.Like(a.Name,"唐")).ToList();

    //ToList()->返回集合
    //First()-> 返回第一个数据,但是必须要有一个,否则会报错
    //FirstOrDefault()->返回第一个数据,可以有也可以没有

    //Single()->符合查询到必须为一个数据,否则报错处理
    //SingleOrDefault()-> 返回一个数据或者没有

    //Last->返回最后一个数据
    //LastOrDefault()->返回最后一个或者没有数据

    //Count()->总计
    //Min()->最小
    //Max()->最大
    //Average()->平均值
    //Sum()->合计

    //翻页获取数据,跳过1个取3个
    //context.Students.Skip(1).Take(3).ToList();

    var first = context.Students.SingleOrDefault(a => a.Id == 7);
    Console.WriteLine(first.Name+"  "+first.StudyClassroom.Name);
    var one = context.Students.Find(7);
    Console.WriteLine("-----------------");
    Console.WriteLine(one.Name + "  " + one.StudyClassroom.Name);
    var oneAsync = context.Students.FindAsync(4);
    Console.WriteLine("-----------------");
    Console.WriteLine(oneAsync.Result.Name+"    "+oneAsync.Result.StudyClassroom.Name);
    //Find()->
}
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "c"."Id", "c"."MathTeacherId", "c"."Name"
      FROM "Classrooms" AS "c"
      WHERE "c"."Name" = '三年八班'
      LIMIT 2
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Name" LIKE '唐%'
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Name" LIKE '唐%'
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (3ms) [Parameters=[@__targetAge_0='18' (DbType = String)], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Age" = @__targetAge_0
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Name" LIKE '唐%'
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE ('唐' = '') OR (instr("s"."Name", '唐') > 0)
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Name" LIKE '唐'
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Id" = 7
      LIMIT 2
唐宝  三年八班
-----------------
唐宝  三年八班
-----------------
蓝菲琳    三年八班

2.3 删除->Delete

var student=context.Students.Single(a => a.Name == "唐宝");

//删除
context.Students.Remove(student);
// context.Students.RemoveRange(student);
// context.Remove(student);
// context.RemoveRange(student);

//保存
var count=context.SaveChanges();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (10ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."Name" = '唐宝'
      LIMIT 2
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (5ms) [Parameters=[@p0='7' (DbType = String)], CommandType='Text', CommandTimeout='30']
      DELETE FROM "Students"
      WHERE "Id" = @p0;
      SELECT changes();

2.4 修改->Updata

一般修改方式

//修改
{
    //一般修改
    {
        var student = context.Students.Single(a => a.Name == "唐宋");
        student.Age += 1;

        //保存
        var count = context.SaveChanges();
    }

    //传参修改
    {
        context.Students.AsNoTracking();

        var student = context.Students.First();
        student.Age += 2;

        context.Students.Update(student);

        context.SaveChanges();
    }
    //
}

3. 输出EF操作的日志信息

首先我们需要增加扩展

Microsoft.Extensions.Logging.Console

using Demo.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo.Data
{
    public class DemoContext:DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseLoggerFactory(ConsoleLoggerFactory)
                .UseSqlite(@"Data Source=C:\Users\xiaocai\Desktop\Code\EFCoreDemo\bin\net5.0\DemoDBSqlite.db");
        }

        public DbSet<Classroom> Classrooms { get; set; }

        public DbSet<Teacher> Teachers { get; set; }

        public DbSet<Student> Students { get; set; }

        public static readonly ILoggerFactory ConsoleLoggerFactory =
            LoggerFactory.Create(builder =>
            {
                builder.AddFilter((category, loglevel) =>
                            category == DbLoggerCategory.Database.Command.Name
                            && loglevel == LogLevel.Information)
                       .AddConsole();
            });
    }
}
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (6ms) [Parameters=[@p0='?', @p1='?' (Size = 3)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Teachers" ("Age", "Name")
      VALUES (@p0, @p1);
      SELECT "Id"
      FROM "Teachers"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@p2='?', @p3='?' (Size = 4)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "Classrooms" ("MathTeacherId", "Name")
      VALUES (@p2, @p3);
      SELECT "Id"
      FROM "Classrooms"
      WHERE changes() = 1 AND "rowid" = last_insert_rowid();

4. 加载数据

加载数据一共分为3种加载方式,分别为:

  • 预加载 -> Eager loading
  • 显示加载 -> Explicit loading
  • 懒加载 -> Lazy loading

4.1 预加载 -> Eager loading

//关联加载
{
    //普通加载
    {
        var classroom = context.Classrooms.ToList();
        foreach (var item in classroom)
        {
            Console.WriteLine("------------分隔符------------");
            foreach (var student in item.ListStu)
            {
                Console.WriteLine(student.Name);
            }
        }
    }

    //预加载
    {
        var classrooms = context.Classrooms.Include(a => a.ListStu).ToList();
    }
}
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "c"."Id", "c"."MathTeacherId", "c"."Name"
      FROM "Classrooms" AS "c"
------------分隔符------------
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "c"."Id", "c"."MathTeacherId", "c"."Name", "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Classrooms" AS "c"
      LEFT JOIN "Students" AS "s" ON "c"."Id" = "s"."StudyClassroomId"
      ORDER BY "c"."Id", "s"."Id"

疯狂套娃方式

var clubs=context.Clubs
        .Where(x=>x.Id>0)
        .Include(x=>x.League)
        .Include(x=>x.Players)
            .ThenInclude(y=>y.Resume)
        .Include(x=>x.Players)
            .ThenInclude(y=>y.GamePlayers)
                .ThenInclude(z=>z.Game)
        .ForstOrDefault();

单独形成类

var students = context.Students
    .Where(a => a.Id > 4)
    .Select(a => new
    {
        a.Id,
        a.Name,
        a.Age
    }) ;

foreach (var item in students)
{
    Console.WriteLine(item.Name);
}

//DbContext 无法追踪匿名类,只能追踪它识别的类
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."Name", "s"."Age"
      FROM "Students" AS "s"
      WHERE "s"."Id" > 4
石延枫
唐宋

4.2 显示加载 -> Explicit loading

//显示加载
{
    var classrooms = context.Classrooms.First();

    Console.WriteLine("------------分隔符------------");

    context.Entry(classrooms)
        .Collection(a => a.ListStu)
        .Load();

    context.Entry(classrooms)
        .Reference(a => a.MathTeacher)
        .Load();
}
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (10ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT "c"."Id", "c"."MathTeacherId", "c"."Name"
      FROM "Classrooms" AS "c"
      LIMIT 1
------------分隔符------------
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (4ms) [Parameters=[@__p_0='10' (Nullable = true) (DbType = String)], CommandType='Text', CommandTimeout='30']
      SELECT "s"."Id", "s"."AddressCity", "s"."Age", "s"."Name", "s"."StudyClassroomId"
      FROM "Students" AS "s"
      WHERE "s"."StudyClassroomId" = @__p_0
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@__p_0='10' (DbType = String)], CommandType='Text', CommandTimeout='30']
      SELECT "t"."Id", "t"."Age", "t"."Name"
      FROM "Teachers" AS "t"
      WHERE "t"."Id" = @__p_0

4.3 懒加载 -> Lazy loading

不建议使用

5. 在EF中直接执行sql语句

5.1 查询语句

// 执行sql
{
    var students = context.Students
                    .FromSqlRaw("select * from Students")
                    .ToList();

    context.Database.ExecuteSqlRaw("delete from Students");
}

6. 在Net Core中配置EF Core

using Demo.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo.Data
{
    public class DemoContext:DbContext
    {
        public DemoContext(DbContextOptions<DemoContext> options):base(options)
        {

        }

        //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        //{
        //    optionsBuilder
        //        .UseLoggerFactory(ConsoleLoggerFactory)
        //        .EnableSensitiveDataLogging()
        //        .UseSqlite(@"Data Source=C:\Users\xiaocai\Desktop\Code\EFCoreDemo\bin\net5.0\DemoDBSqlite.db");
        //}

        public DbSet<Classroom> Classrooms { get; set; }

        public DbSet<Teacher> Teachers { get; set; }

        public DbSet<Student> Students { get; set; }

        public static readonly ILoggerFactory ConsoleLoggerFactory =
            LoggerFactory.Create(builder =>
            {
                builder.AddFilter((category, loglevel) =>
                            category == DbLoggerCategory.Database.Command.Name
                            && loglevel == LogLevel.Information)
                       .AddConsole();
            });
    }
}


---appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "ConnectionStrings": {
    "LocalDB": "Data Source=C:\\Users\\xiaocai\\Desktop\\Code\\EFCoreDemo\\bin\\net5.0\\DemoDBSqlite.db"
  },
  "AllowedHosts": "*"
}

using Demo.Data;
using Demo.Domain;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Demo.Web.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        DemoContext _demoContext = null;

        public WeatherForecastController(ILogger<WeatherForecastController> logger,
            DemoContext context)
        {
            _logger = logger;
            _demoContext = context;
        }

        [HttpGet]
        public IEnumerable<Student> Get()
        {
            var students = _demoContext.Students.ToList();
            return students;
        }
    }
}



public class Startup
{

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddDbContext<DemoContext>(options =>
        {
            options.UseSqlite(Configuration.GetConnectionString("LocalDB"));
        });
    }

}

CSDN震惊部,保姆式教学C#的EFCore,一步一步带你入门

上一篇:四十一、如何复制表


下一篇:聊一聊编程