更新记录
转载请注明出处:
2022年10月15日 发布。
2022年10月10日 从笔记迁移到博客。
DbContext对象介绍(数据库上下文对象)
数据库上下文对象说明
A DbContext instance represents a session with the database and can be used to query and save instances of your entities
DbContext is a combination of the Unit Of Work and Repository patterns
DbContext 类是EF Core的核心
一个DbContext实例代表一个与数据库的会话(session)
可以用于查询和保存数据到数据库
注意:DBContext不是一个线程安全的对象(thread safe object)
DbContext主要功能
Manage database connection(管理数据库连接)
Configure model & relationship(配置模型和模型之间的关系)
Querying database(查询数据库的数据)
Saving data to the database(保存数据到数据库)
Configure change tracking(管理变化跟踪)
Caching(缓存)
Transaction management(事务管理)
DbContext使用
DbContext类型定义
使用DbContext类型需要创建一个继承其的子类
通常包含 DbSet
public class PandaDbContext : DbContext
{
//无参数的构造函数
public PandaDbcontext()
{
}
//有参数的构造函数
public PandaDbcontext(DbContextOptions<PandaDbcontext> dbContextOptions) : base(dbContextOptions)
{
}
//配置Dbcontext
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
//配置模型,比如FluentAPI
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
//实体模型
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
}
待完善:https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/
如何使用OnConfiguring
DbContext对象实例化
因为DbContext会占用一定的资源最好使用后就进行释放
using(DbContext db = new DbContext())
{
//保存修改
db.SaveChanges();
//保存修改(异步)
db.SaveChangesAsync();
}
Database属性
说明
Database属性用于提供数据库的管理支持,如连接、命令和事务
这个属性在数据库上实现了一个facade
返回一个System.Data.Entity.Database对象
常用方法使用
using(Model1 model = new Model1())
{
//获得database对象
System.Data.Entity.Database database = model.Database;
//获得执行的SQL记录
//注意:这是一个委托,参数为string,无返回值
database.Log = Console.WriteLine;
//获得连接信息
var conn = database.Connection;
//获得连接字符串
Console.WriteLine(conn.ConnectionString);
//获得连接的状态
Console.WriteLine(conn.State);
//获得连接的数据库服务器
Console.WriteLine(conn.DataSource);
//获得连接的数据库
Console.WriteLine(conn.Database.ToString());
//获得连接到的服务器版本
Console.WriteLine(conn.ServerVersion);
}
进行数据库的直接增删改查
using(PandaContext db = new PandaContext())
{
//SQL查询
var queryResult = db.Database.SqlQuery<Product>("SQL语句", new Object[3] {
new SqlParameter("@abc1","Value"),
new SqlParameter("@abc2","Value"),
new SqlParameter("@abc3","Value")
});
//SQL增删改
db.Database.ExecuteSqlCommand("SQL语句");
}
ContextId属性
每个上下文都有一个唯一的id(unique id)
Model属性
Model属性保存数据库中映射的基础实体和关系的元数据
ChangeTracker属性
变化追踪器
可用于确定是否启用了LazyLoading以及上下文实体是否有更改
并可用于操作,如接受更改和级联删除
常用方法
Method | Purpose |
---|---|
Add/AddAsync | Allows insertion of the entity into the database |
AddRange/AddRangeAsync | |
Find/FindAsync | Find a specific entity by Id |
OnConfiguring | Allows for us to override the options |
OnModelCreating | Allows us to use the to further define our entities and their relationships |
Remove | Delete an entity from the database |
SaveChanges/ SaveChangesAsync | Apply the tracked changes in a single transaction |
Update | Used to perform an update to the tracked entity |
Method | Usage |
Add | Adds a new entity to DbContext with Added state and starts tracking it. This new entity data will be inserted into the database when SaveChanges() is called. |
AddAsync | Asynchronous method for adding a new entity to DbContext with Added state and starts tracking it. This new entity data will be inserted into the database when SaveChangesAsync() is called. |
AddRange | Adds a collection of new entities to DbContext with Added state and starts tracking it. This new entity data will be inserted into the database when SaveChanges() is called. |
AddRangeAsync | Asynchronous method for adding a collection of new entities which will be saved on SaveChangesAsync(). |
Attach | Attaches a new or existing entity to DbContext with Unchanged state and starts tracking it. |
AttachRange | Attaches a collection of new or existing entities to DbContext with Unchanged state and starts tracking it. |
Entry | Gets an EntityEntry for the given entity. The entry provides access to change tracking information and operations for the entity. |
Find | Finds an entity with the given primary key values. |
FindAsync | Asynchronous method for finding an entity with the given primary key values. |
Remove | Sets Deleted state to the specified entity which will delete the data when SaveChanges() is called. |
RemoveRange | Sets Deleted state to a collection of entities which will delete the data in a single DB round trip when SaveChanges() is called. |
SaveChanges | Execute INSERT, UPDATE or DELETE command to the database for the entities with Added, Modified or Deleted state. |
SaveChangesAsync | Asynchronous method of SaveChanges() |
Set | Creates a DbSet |
Update | Attaches disconnected entity with Modified state and start tracking it. The data will be saved when SaveChagnes() is called. |
UpdateRange | Attaches a collection of disconnected entities with Modified state and start tracking it. The data will be saved when SaveChagnes() is called. |
OnConfiguring | Override this method to configure the database (and other options) to be used for this context. This method is called for each instance of the context that is created. |
OnModelCreating | Override this method to further configure the model that was discovered by convention from the entity types exposed in DbSet |
增删改查操作
添加数据
using(PandaContext db = new PandaContext())
{
//新建数据
PandaTable pandaTable1 = new PandaTable()
{
Id = 54088,
Name = "Dog8899",
Code = "8899",
Note = "www.Dog.com"
};
//新建数据
PandaTable pandaTable2 = new PandaTable()
{
Id = 54089,
Name = "Dog8899",
Code = "8899",
Note = "www.Dog.com"
};
//添加数据(单条)
db.PandaTable.Add(pandaTable1);
//添加数据(多条)
db.PandaTable.AddRange(new PandaTable[] { pandaTable1,pandaTable2 });
//保存到数据库
db.SaveChanges();
}
删除数据
//reload
context.Entry(表).Reload();
using(PandaContext db = new PandaContext())
{
//查询数据
var queryResult = from item in db.PandaTable
where item.Id >= 6
select item;
//转为List
List<PandaTable> pandaTables = queryResult.ToList<PandaTable>();
//移除数据(单条)
if (pandaTables.Count() > 0)
{
db.PandaTable.Remove(pandaTables[0]);
}
//移除数据(多条)
db.PandaTable.RemoveRange(queryResult);
//保存到数据库
db.SaveChanges();
}
更新/修改数据
更新/修改数据
using(PandaContext db = new PandaContext())
{
//查询数据
var queryResult = from item in db.PandaTable
where item.Id == 5
select item;
//转为List
List<PandaTable> pandaTables = queryResult.ToList<PandaTable>();
//修改数据
if(pandaTables.Count() > 0)
{
pandaTables[0].Name = "NewMonkey";
pandaTables[0].Note = "NewMonkeyNewMonkeyNewMonkey";
}
//保存到数据库
db.SaveChanges();
}
查询数据-使用LINQ
using(PandaContext db = new PandaContext())
{
//查找指定数据
var qureyResult = from item in db.PandaTable
where item.Id == 1
select item;
foreach (var item in qureyResult)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Name);
Console.WriteLine(item.Code);
Console.WriteLine(item.Note);
}
}
查询数据-使用Find
using(PandaContext db = new PandaContext())
{
//查找指定的数据使用Find方法
//注意:参数为表的主键
//注意:如果有多个主键需要传入多个参数
PandaTable pandaTable = db.PandaTable.Find(5);
//使用数据
if (pandaTable != null)
{
Console.WriteLine(pandaTable.Id);
Console.WriteLine(pandaTable.Name);
Console.WriteLine(pandaTable.Code);
Console.WriteLine(pandaTable.Note);
}
}
查询数据-执行SQL代码
using(PandaContext db = new PandaContext())
{
//执行SQL代码
string sql = "SELECT * FROM PandaTable where Id = @Id";
//绑定的参数值
SqlParameter id = new SqlParameter("Id", 5);
var queryResult = db.PandaTable.SqlQuery(sql, id);
foreach (var item in queryResult)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Name);
Console.WriteLine(item.Code);
Console.WriteLine(item.Note);
}
}
查询的结果转为List和Array
using(PandaContext db = new PandaContext())
{
//查询数据
var queryResult = from item in db.PandaTable
where item.Id >= 6
select item;
//转为List
List<PandaTable> pandaTables = queryResult.ToList<PandaTable>();
//转为Array
PandaTable[] pandaTables1 = queryResult.ToArray<PandaTable>();
}
获得查询的具体SQL
using(PandaContext db = new PandaContext())
{
var qureyResult = from item in db.PandaTable
where item.Id == 1
select item;
//获得查询的具体SQL
Console.WriteLine(qureyResult.ToString());
}
重新载入更新后的数据
using(PandaContext db = new PandaContext())
{
//查询数据
var queryResult = from item in db.PandaTable
where item.Id == 5
select item;
//转为List
List<PandaTable> pandaTables = queryResult.ToList<PandaTable>();
//修改数据
if(pandaTables.Count() > 0)
{
pandaTables[0].Name = "666NewMonkey";
pandaTables[0].Note = "666NewMonkeyNewMonkeyNewMonkey";
}
//保存到数据库
db.SaveChanges();
//更新完成从新载入更新后的结果
db.Entry(pandaTables[0]).Reload();
//再查询数据
var queryResult2 = from item in db.PandaTable
where item.Id == 5
select item;
//输出数据
foreach (var item in queryResult2)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Name);
Console.WriteLine(item.Note);
}
}
using(PandaContext db = new PandaContext())
{
//查询数据
var queryResult = from item in db.PandaTable
where item.Id == 5
select item;
//转为List
List<PandaTable> pandaTables = queryResult.ToList<PandaTable>();
//修改数据
if(pandaTables.Count() > 0)
{
pandaTables[0].Name = "NewMonkey";
pandaTables[0].Note = "NewMonkeyNewMonkeyNewMonkey";
}
//保存到数据库
db.SaveChanges();
}
查询数据-使用LINQ
using(PandaContext db = new PandaContext())
{
//查找指定数据
var qureyResult = from item in db.PandaTable
where item.Id == 1
select item;
foreach (var item in qureyResult)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Name);
Console.WriteLine(item.Code);
Console.WriteLine(item.Note);
}
}
查询数据-使用Find
using(PandaContext db = new PandaContext())
{
//查找指定的数据使用Find方法
//注意:参数为表的主键
//注意:如果有多个主键需要传入多个参数
PandaTable pandaTable = db.PandaTable.Find(5);
//使用数据
if (pandaTable != null)
{
Console.WriteLine(pandaTable.Id);
Console.WriteLine(pandaTable.Name);
Console.WriteLine(pandaTable.Code);
Console.WriteLine(pandaTable.Note);
}
}
查询数据-执行SQL代码
using(PandaContext db = new PandaContext())
{
//执行SQL代码
string sql = "SELECT * FROM PandaTable where Id = @Id";
//绑定的参数值
SqlParameter id = new SqlParameter("Id", 5);
var queryResult = db.PandaTable.SqlQuery(sql, id);
foreach (var item in queryResult)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Name);
Console.WriteLine(item.Code);
Console.WriteLine(item.Note);
}
}
查询的结果转为List和Array
using(PandaContext db = new PandaContext())
{
//查询数据
var queryResult = from item in db.PandaTable
where item.Id >= 6
select item;
//转为List
List<PandaTable> pandaTables = queryResult.ToList<PandaTable>();
//转为Array
PandaTable[] pandaTables1 = queryResult.ToArray<PandaTable>();
}
获得查询的具体SQL
using(PandaContext db = new PandaContext())
{
var qureyResult = from item in db.PandaTable
where item.Id == 1
select item;
//获得查询的具体SQL
Console.WriteLine(qureyResult.ToString());
}
重新载入更新后的数据
using(PandaContext db = new PandaContext())
{
//查询数据
var queryResult = from item in db.PandaTable
where item.Id == 5
select item;
//转为List
List<PandaTable> pandaTables = queryResult.ToList<PandaTable>();
//修改数据
if(pandaTables.Count() > 0)
{
pandaTables[0].Name = "666NewMonkey";
pandaTables[0].Note = "666NewMonkeyNewMonkeyNewMonkey";
}
//保存到数据库
db.SaveChanges();
//更新完成从新载入更新后的结果
db.Entry(pandaTables[0]).Reload();
//再查询数据
var queryResult2 = from item in db.PandaTable
where item.Id == 5
select item;
//输出数据
foreach (var item in queryResult2)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Name);
Console.WriteLine(item.Note);
}
}
使用本地数据集
本地数据集说明
当添加/查询数据库的数据时,会在本地的Local数据集中保存一份
通过使用本地数据可以缓解数据库的压力
使用方法
使用数据集的Local方法即可
using(PandaContext db = new PandaContext())
{
//获得数据库中数据的条数
db.PandaTable.Count();
//获得本地DataSet中数据的条数
db.PandaTable.Local.Count();
}
Local本地数据集数据查询
在ASP.NET Core中将DbContext注入到服务容器中
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
}
DbContextOptionsBuilder 对象
说明
数据库上下文对象的配置项的配置器
用于生成具体的配置项
检测是否已经配置了配置项
使用IsConfigured属性
获得DBContextOptions对象
使用Options属性
常用方法
Name | Method or Extension | Purpose |
---|---|---|
AddInterceptors | Method | Allows adding a list of interceptors to monitor or modify operations |
Configure Warnings | Method | Used to change runtime behavior of warnings, can impact performance |
EnableDetailed Errors | Method | Used to include detailed error messages generated by exceptions, can impact performance |
EnableSensitive DataLogging | Method | Allows information to be logged that would ordinarily be suppressed, can be a security risk |
UseInMemory Database | Extension | Allows the context to work against an in-memory database |
UseLazyLoading Proxies | Extension | Enables the creation of proxies for lazy loading |
UseSqlLite | Extension | Sets the context to use SQL Lite for the underlying storage. |
UseSqlServer | Extension | Sets the context to use SQL Server for the underlying storage |
DBContextOptions对象
说明
数据库上下文对象的配置项对象
常用属性
ContextType
Gets the type for the context, if no type is defined, then DBContext will be returned
Extensions
Gets a list of Extensions as configured, such as the type of database being leveraged
IsFrozen
Used to determine if the Context is open for further configuration.
If true, the system cannot further override the context options in the OnConfiguring method
DataSet
DataSet说明
DataSet数据实体状态
应用程序更改数据对象会引发数据集状态的变更
可能出现的状态有:
Added 添加实体对象创建到实体集中,数据未添加进数据库
Modified 实体对象已经存在于实体数据集中,数据库同时存在对应的数据,但某些实体对象属性值已经变更,未更新到数据库中
Deleted 实体对象已经存在于实体数据集中,数据库同时存在对应的数据,但是实体对象本身被标识为删除
Unchanged 实体对象存在于数据集中,数据库同时包含对应未曾更改的相同数据
Detached 实体对象已经不在数据集中
注意:当实体对象我Added或Modified状态时,调用SaveChanges方法变更数据成功后,状态会调整到Unchanged;当实体对象状态在Deleted时,调用SaveChanges方法后,状态会调整到Detached
注意:每一个数据对象均有其专属的状态,要获得状态信息,可以使用DbContext的Entry方法
使用该方法可以获得每个实体自身的状态
contextObject.Entry(entityTypeObject).State
该属性的类型是一个EntityState枚举值,分别为:
EntityState.Added
EntityState.Modified
EntityState.Deleted
EntityState.Unchanged
EntityState.Detached
实例:
using(PandaModel pandaModel = new PandaModel())
{
OrderDetail orderDetail = pandaModel.OrderDetail.First();
//输出状态
Console.WriteLine(pandaModel.Entry(orderDetail).State);
pandaModel.OrderDetail.Remove(orderDetail);
//输出状态
Console.WriteLine(pandaModel.Entry(orderDetail).State);
int affectRows = pandaModel.SaveChanges();
Console.WriteLine("Success! {0}",affectRows);
//输出状态
Console.WriteLine(pandaModel.Entry(orderDetail).State);
}
主要方法
Name | Method or Extension | Purpose |
---|---|---|
Add | Method | Add the entity to the context for insert |
AsNoTracking | Method | Gets an entity that is not tracked so that any modifications do not cause concurrency issues |
Create | Method | Creates a new entity for the type T |
Find/FindAsync | Method | Locates an entity by Id and attaches the entity |
Include | Method | Used to fetch related entities |
Remove | Method | Sets the entity as deleted in the context |
SqlQuery | Method | Allows execution of a raw SQL Query |
AddOrUpdate | Extension | Inserts the entity if it does not exist or updates the entity if it does exist |
ChangeTracker
说明
变化追踪器
The DbContext in Entity Framework Core includes the ChangeTracker class in Microsoft.EntityFrameworkCore.ChangeTracking namespace
tracking the state of each entity retrieved using the same DbContext instance
实例
实例:获得每个实体的状态
using System;
using ConsoleApp7.Repository;
using ConsoleApp7.Models;
using System.Linq;
namespace ConsoleApp7
{
class Program
{
static void Main(string[] args)
{
using(PandaDbContext db = new PandaDbContext())
{
Product product = new Product()
{
ProductTitle = "Panda666",
Price = 666.66M
};
User user = new User()
{
UserTitle = "panda666",
age = 8888888
};
foreach (var item in db.ChangeTracker.Entries())
{
Console.WriteLine($"{item.Entity} : {item.State}");
}
Console.WriteLine("============================================");
db.Products.Add(product);
db.Users.Add(user);
foreach (var item in db.ChangeTracker.Entries())
{
Console.WriteLine($"{item.Entity} : {item.State}");
}
//保存设置
db.SaveChanges();
Console.WriteLine("============================================");
db.Products.Remove(db.Products.First());
foreach (var item in db.ChangeTracker.Entries())
{
Console.WriteLine($"{item.Entity} : {item.State}");
}
Console.WriteLine("============================================");
//保存设置
db.SaveChanges();
}
//wait
Console.ReadKey();
}
}
}
初始化数据
在OnModelCreating中定义初始化数据
HasData方法接收一个可变参数数组
即可以添加一个或多个相同的实体类型
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Author>().HasData(
new Author
{
Id = new Guid("72D5B5F5-3008-49B7-B0D6-CC337F1A3330"),
Name = "Author 1",
BirthDate = new DateTimeOffset(new DateTime(1960, 11,18)),
Email = "[email protected]"
},
//…
);
}
使用初始化数据扩展类
如果添加的初始数据比较多,建议单独抽出
如果要添加的测试数据比较多,为了保持LibraryDbContext类的简洁清晰
可以为ModelBuilder类创建扩展方法,并在扩展方法中添加数据
定义:
public static class ModelBuilderExtension
{
public static void SeedData(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>().HasData(…);
modelBuilder.Entity<Book>().HasData(…);
}
}
使用:
在Context类的OnModelCreating方法中
只需调用扩展方法modelBuilder.SeedData()即可
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.SeedData();
}
标签:Console,WriteLine,item,db,Entity,Framework,Context,new,PandaContext
From: https://www.cnblogs.com/cqpanda/p/16778277.html