先来一张祖师爷镇楼。
哎呀呀! 搞错了搞错了,当然应该是这个头发多的…
在之前的时候博主介绍过关于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
安装这个类库,会自动安装如下内容:
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
引入完成之后,会产生如下依赖包信息:
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>
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;
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.
PM> update-database
Build started...
Build succeeded.
Applying migration '20210704073825_ChangeSomeProperties'.
Done.
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();
}
批量增加
//批量增加
{
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"));
});
}
}