当前位置: 首页 > 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.dtcms.com/a/302256.html

相关文章:

  • 归雁思维:解锁自然规律与人类智慧的桥梁
  • Online Proofing System(OPS)在线校样系统使用说明
  • Linux进程概念(五)进程地址空间
  • Leaflet 综合案例 - 路径规划
  • 医疗领域非结构化数据处理技术突破与未来演进
  • svn与git Merge重要区别讲解
  • C# 提取字符串 指定开始和结尾字符
  • 人机交互打字游戏
  • C#高级:通过修改注册表实现系统代理服务器的启用、编辑和禁用
  • 【计算机网络】计算机网络中光猫、交换机、路由器、网关、MAC地址是什么?两台电脑是如何联通的?
  • 承装修试二级承包范围
  • 3DGRUT: 革命性的3D高斯粒子光线追踪与混合光栅化技术深度解析
  • mac电脑如何关闭防火墙
  • 反欺诈系统:Oracle 到 ES 迁移实战
  • keepalive
  • 8.异常处理--Exceptions
  • 代码随想录Day32:动态规划(斐波那契数、爬楼梯、使用最小花费爬楼梯)
  • 字节跳动开源Coze,开启AI Agent开发新时代?
  • 我从 Web2 转型到 Web3 的 9 条经验总结
  • linux命令grep的实际应用
  • Leetcode——11. 盛最多水的容器
  • kubectl中的yaml配置详解
  • 前段面试题新版
  • 从fork到exit:剖析Linux进程的诞生、消亡机制
  • 零基础部署网站?使用天翼云服务搭建语音听写应用系统
  • C++ list 容器全解析:从构造到模拟实现的深度探索----《Hello C++ Wrold!》(16)--(C/C++)
  • [机缘参悟-237]:AI人工神经网络与人类的神经网络工作原理的相似性
  • 嵌入式学习(40)-基于STM32F407Hal库的串口DMA空闲中断接收+DMA发送
  • 前端实现银河粒子流动特效的技术原理与实践
  • 物联网与数字孪生:深度协同驱动智能未来 —— 专业规划分析