> For the complete documentation index, see [llms.txt](https://monksoul.gitbook.io/hoa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://monksoul.gitbook.io/hoa/shujukucaozuoshinan/efcoregaoxingneng.md).

# 9.14、EF Core 高性能

## 高性能建议

* 请以**异步方式**调用所有数据访问 api。&#x20;
* 检索的数据不是必需的。 编写查询以**仅返回当前 HTTP 请求所必需**的数据。&#x20;
* 如果数据可以接受，请考虑缓存经常访问的从数据库或远程服务检索的数据。 使用 MemoryCache 或 microsoft.web.distributedcache ，具体取决于方案。
* &#x20;**尽量减少网络往返次数**。 目标是使用单个调用而不是多个调用来检索所需数据。
* &#x20;**在访问数据时，请不要在 Entity Framework Core 中使用无跟踪查询**。 EF Core 可以更有效地返回无跟踪查询的结果。 筛选和聚合 LINQ 查询（例如， .Where使用.Select、或.Sum语句），以便数据库执行筛选。
* &#x20;请考虑 EF Core**在客户端上解析一些查询运算符**，这可能导致查询执行效率低下。&#x20;
* &#x20;**不要对集合使用投影查询**，这可能会导致执行 "N + 1" 个 SQL 查询。&#x20;
* 使用 `DbContextPool` 池来管理 `DbContext`，类似 ADO.NET 的连接池。
* 手动或显式编译的查询 API，允许应用程序缓存查询转换，使其可仅被计算一次并执行多次。

```csharp
// Create an explicitly compiled query
private static Func<CustomerContext, int, Customer> _customerById =
    EF.CompileQuery((CustomerContext db, int id) =>
        db.Customers
            .Include(c => c.Address)
            .Single(c => c.Id == id));

// Use the compiled query by invoking it
using (var db = new CustomerContext())
{
   var customer = _customerById(db, 147);
}
```

## 将DbContext分成多个子DbContext

正常情况下，我们的系统只有一个继承 `DbContext` 的类，也就是我们所有模型、存储过程、视图、函数等都是写在这个类中。随着系统越来越复杂，这个类也就越来越大，这样就会大大影响 `DbContext` 首次冷加载的时候会加载所有定义的模型、存储过程、视图、函数等。

所以、建议我们把系统划分成多个子模块，每一个子模块有自己独立的 `DbContext` 类，这样冷加载的性能大大提升，数据库操作也就响应越来越快！

具体怎么实现多个 `DbContext` 查查阅 [9.11、多上下文、读写分离](https://monksoul.gitbook.io/hoa/shujukucaozuoshinan/duoshangxiawen_duxiefenli) 章节。

## 启用行版本控制功能

```sql
-- 设置为单用户
ALTER DATABASE AlliantDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
-- 开启行版本（事务级)
ALTER DATABASE AlliantDB SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
-- 开启语句级行版本
ALTER DATABASE AlliantDB SET READ_COMMITTED_SNAPSHOT ON WITH no_wait
GO
-- 设置为多用户
ALTER DATABASE AlliantDB SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://monksoul.gitbook.io/hoa/shujukucaozuoshinan/efcoregaoxingneng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
