当前位置: 首页 > news >正文

Entity Framework Core (EF Core) 中Database

在 Entity Framework Core (EF Core) 中,Database属性的类型是DatabaseFacadeDatabaseFacade 是一个关键的门面类,提供对数据库相关操作的统一访问接口。它封装了与底层数据库交互的核心功能,包括连接管理、事务处理、执行原始 SQL 以及数据库迁移等操作。下面从功能、用法、常见场景和最佳实践几个方面详细解析:

1. 核心功能

DatabaseFacade 提供以下主要功能:

// 获取底层 DbConnection
var connection = context.Database.GetDbConnection();// 检查连接状态
if (context.Database.GetDbConnection().State != ConnectionState.Open)
{await context.Database.OpenConnectionAsync();
}// 执行连接相关操作
var databaseName = context.Database.GetDbConnection().Database;
1.2 事务处理
// 开始事务
await using var transaction = await context.Database.BeginTransactionAsync();try
{// 执行数据操作context.Users.Add(new User { Name = "John" });await context.SaveChangesAsync();// 提交事务await transaction.CommitAsync();
}
catch (Exception)
{// 回滚事务await transaction.RollbackAsync();
}
1.3 执行原始 SQL
// 执行查询
var users = await context.Users.FromSqlRaw("SELECT * FROM Users WHERE Age > {0}", 18).ToListAsync();// 执行非查询命令
var rowsAffected = await context.Database.ExecuteSqlRawAsync("UPDATE Users SET LastLogin = GETDATE() WHERE Id = {0}", 1);
1.4 数据库迁移
// 应用所有待迁移的更改
await context.Database.MigrateAsync();// 检查是否需要迁移
bool pendingMigrations = (await context.Database.GetPendingMigrationsAsync()).Any();// 创建数据库(如果不存在)
await context.Database.EnsureCreatedAsync();
1.5 数据库状态检查
// 检查数据库是否存在
bool exists = await context.Database.EnsureExistsAsync();// 检查数据库架构是否与模型匹配
bool isCompatible = await context.Database.CanConnectAsync();

2. 获取 DatabaseFacade 实例

在 DbContext 中,可以通过 Database 属性访问 DatabaseFacade

public class ApplicationDbContext : DbContext
{public DbSet<User> Users { get; set; }// 通过基类的 Database 属性访问 DatabaseFacadepublic void SomeMethod(){// 执行数据库操作this.Database.ExecuteSqlRaw("UPDATE Users SET ...");}
}

3. 常见应用场景

3.1 复杂查询优化

对于 EF Core 查询性能不佳的场景,使用原始 SQL:

var results = await context.Set<ComplexResult>().FromSqlRaw("EXEC sp_GetComplexData @Param1, @Param2", param1, param2).ToListAsync();
3.2 批量操作

执行批量更新或删除:

await context.Database.ExecuteSqlRawAsync("DELETE FROM Orders WHERE OrderDate < {0}", DateTime.Now.AddYears(-1));
3.3 数据库初始化与迁移

在应用启动时确保数据库和架构存在:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{using (var scope = app.ApplicationServices.CreateScope()){var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();context.Database.Migrate(); // 应用所有迁移}// 其他配置...
}
3.4 分布式事务

结合 ADO.NET 使用分布式事务:

await using var transaction = await context.Database.BeginTransactionAsync();try
{// EF Core 操作context.Users.Add(new User { Name = "Alice" });await context.SaveChangesAsync();// ADO.NET 操作(使用相同连接)var connection = context.Database.GetDbConnection();using (var command = connection.CreateCommand()){command.Transaction = transaction.GetDbTransaction();command.CommandText = "UPDATE Log SET Status = 'Processed' WHERE Id = 1";await command.ExecuteNonQueryAsync();}await transaction.CommitAsync();
}
catch (Exception)
{await transaction.RollbackAsync();throw;
}

4. 高级用法

4.1 控制连接超时
context.Database.SetCommandTimeout(TimeSpan.FromMinutes(2)); // 设置 2 分钟超时
4.2 拦截数据库操作

通过自定义拦截器记录 SQL 执行时间:

public class SqlLoggingInterceptor : DbCommandInterceptor
{private readonly ILogger _logger;public SqlLoggingInterceptor(ILogger<SqlLoggingInterceptor> logger){_logger = logger;}public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result){_logger.LogInformation("Executing SQL: {Sql}", command.CommandText);return base.ReaderExecuting(command, eventData, result);}
}// 在 DbContext 中注册拦截器
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{optionsBuilder.AddInterceptors(new SqlLoggingInterceptor(_logger));
}
4.3 多数据库操作

在多个 DbContext 之间共享事务:

await using var transaction = await context1.Database.BeginTransactionAsync();try
{// 操作 context1context1.Users.Add(new User { Name = "Bob" });await context1.SaveChangesAsync();// 操作 context2(使用相同事务)context2.Orders.Add(new Order { UserId = 1 });await context2.SaveChangesAsync();await transaction.CommitAsync();
}
catch (Exception)
{await transaction.RollbackAsync();throw;
}

5. 注意事项

5.1 原始 SQL 的安全性

始终使用参数化查询,避免 SQL 注入:

// 安全写法
await context.Database.ExecuteSqlRawAsync("UPDATE Users SET Name = {0} WHERE Id = {1}", newName, id);// 不安全写法(避免)
await context.Database.ExecuteSqlRawAsync($"UPDATE Users SET Name = '{newName}' WHERE Id = {id}");
5.2 跨数据库兼容性

直接编写的 SQL 可能不支持多种数据库提供者(如 SQL Server 和 PostgreSQL 的语法差异)。

5.3 事务边界

确保事务的生命周期正确管理,避免长时间持有事务导致锁争用。

5.4 性能考虑

频繁调用 DatabaseFacade 方法可能影响性能,优先使用 EF Core 的 LINQ 查询。

总结

DatabaseFacade 是 EF Core 中连接应用程序和底层数据库的桥梁,提供了丰富的数据库操作功能。它在需要执行原始 SQL、管理事务或进行数据库迁移时特别有用。但在使用时应权衡其灵活性与潜在风险,遵循最佳实践以确保代码的安全性和可维护性。在大多数情况下,优先使用 EF Core 的高级 API,仅在必要时才通过 DatabaseFacade 进行底层操作。

http://www.lryc.cn/news/602092.html

相关文章:

  • uniapp,uview icon加载太慢了,老是显示叉叉,将远程加载改到本地加载。
  • 设计模式(二十三)行为型:模板方法模式详解
  • 常用设计模式系列(十四)—模板方法模式
  • 开源智能体-JoyAgent集成ollama私有化模型
  • C#与C++交互开发系列(二十六):构建跨语言共享缓存,实现键值对读写与数据同步(实践方案)
  • 基于百度 iframe 框架与语音解析服务的数字人交互系统实现
  • 元宇宙工厂前端新形态:Three.js与WebGL实现3D产线交互的轻量化之路
  • Python系统交互库全解析
  • CentOS 7 安装 dnsmasq 解决nginx无法指定dns的问题
  • 新能源行业B端极简设计:碳中和目标下的交互轻量化实践
  • GitLab 18.2 发布几十项与 DevSecOps 有关的功能,可升级体验【三】
  • Windows 系统分辨率切换** 与 **Qt4 无边框窗口管理机制** 的交互
  • 全面解析MySQL(4)——三大范式与联合查询实例教程
  • Deep Learning_ Foundations and Concepts-Springer (2024)【拜读】前向编码器20章
  • 【CSS】设置表格表头固定
  • 深度学习----视觉里程计
  • 工业场景工服识别准确率↑32%!陌讯多特征融合算法实战解析
  • STM32 usb HOST audio USB 音频设备 放音乐
  • Pandas 里的分箱操作
  • 负载均衡集群HAproxy
  • MCP工作原理
  • Java-泛型类的定义与使用
  • 浅谈面试中的递归算法
  • 【Linux】编辑器vim和编译器gcc/g++
  • 解析分区、挂载与块设备:Linux 存储管理核心命令详解
  • 近屿智能正式发布AI得贤招聘官的AI面试官智能体6.3版本:交付替代人类面试官的打分结果
  • 零基础学习性能测试第九章:全链路追踪-项目实操
  • Jenkins + SonarQube 从原理到实战一:基于 K8s 部署与使用(含中文插件与 Python 扫描)
  • 力扣1457. 二叉树中的伪回文路径
  • 力扣面试150(42/150)