DbContext 文件中有很多 DBSet 会影响性能吗?
Can having a lot of DBSets in the DbContext file affect performance?
我们的 MySQL 数据库中有大量的 table(大约 1800 个),大多数时候,每个开发人员都会创建自己的项目并添加一个仅包含必要 tables 为 DbSet
s。我的一位同事建议创建一个包含数据库中每个 table 的项目,并在每个项目之间共享它。这会影响性能吗?例如,它会在启动时或 运行 学分期间减慢程序速度吗?
大型 DbContext 的初始化速度可能较慢,这是首次使用 DbContext
时的 one-off 成本。这也是 DbContext
可能由于无效的模式配置而失败的时候。您可以在 service/application 启动时通过发出一个简单的查询来“预热”DbContext
。例如:
// Check application DB version and warm the DbContext.
using (var context = new AppDbContext())
{
var dbVersion = context.AppConfig.Select(x => x.DbVersion).Single();
if (dbVersion < MinimumDbVersion)
throw new ApplicationException("The application database version is too low.");
}
其中数据库有一个 AppConfig table,其中包含包括 DbVersion 在内的配置设置。基本上它可以是任何东西,加载配置设置,或者简单地做一个 Count
用户等等。只要查询执行,DbContext的静态初始化就会执行。
初始化所需的时间长度与 DbSet
声明并没有真正关联,而是与 DbContext
需要注意的实体总数有关.即使您有 100 个“top-level”实体并为它们定义了 DbSet
,如果这些实体展开以揭示与另外 1700 个实体的关系,那么这实际上与 1800 个 DbSet 的工作量相同。
限界上下文是一个将实体拆分为“上下文”的过程,其中每个 DbContext
服务于系统的一个关键区域。这既减少了每个 DbContext
需要了解的实体数量,加快了初始化速度,但它也有助于更好地组织代码以专注于实体,甚至是与该区域相关的基础数据的表示。实体可以在 DbContext
个实例之间共享,但您应该设法确保只有一个 DbContext
负责编写该实体。例如,您可以定义单独的 DbContext
实例来管理客户和管理订单。订单需要了解他们的客户,但 create/update 客户信息是 CustomerDbContext 的责任,而不是 OrderDbContext。一种选择是在 OrderDbContext 中使用类似于 CustomerSummary 实体的东西来映射订单上下文中客户的基本详细信息。理想情况下,DbContext 应该检查 SaveChanges 上的 inserted/updated/deleted 更改跟踪器中存在哪些实体类型,如果出现它们负责的实体类型以外的任何实体类型,则抛出异常。
通常归咎于大小的 DbContext 的典型性能杀手通常允许 DbContext 实例存在时间过长并跟踪太多实体。 DbContext 知道的实体越多,他们就越容易最终跟踪更多的实体,而开发人员没有意识到实例打开的时间太长。假设更大的上下文创建起来“更昂贵”,因此它打开和传递的时间更长 around/persisted 以避免感知成本,这会导致该实例逐渐被跟踪实例膨胀而导致性能成本。
我们的 MySQL 数据库中有大量的 table(大约 1800 个),大多数时候,每个开发人员都会创建自己的项目并添加一个仅包含必要 tables 为 DbSet
s。我的一位同事建议创建一个包含数据库中每个 table 的项目,并在每个项目之间共享它。这会影响性能吗?例如,它会在启动时或 运行 学分期间减慢程序速度吗?
大型 DbContext 的初始化速度可能较慢,这是首次使用 DbContext
时的 one-off 成本。这也是 DbContext
可能由于无效的模式配置而失败的时候。您可以在 service/application 启动时通过发出一个简单的查询来“预热”DbContext
。例如:
// Check application DB version and warm the DbContext.
using (var context = new AppDbContext())
{
var dbVersion = context.AppConfig.Select(x => x.DbVersion).Single();
if (dbVersion < MinimumDbVersion)
throw new ApplicationException("The application database version is too low.");
}
其中数据库有一个 AppConfig table,其中包含包括 DbVersion 在内的配置设置。基本上它可以是任何东西,加载配置设置,或者简单地做一个 Count
用户等等。只要查询执行,DbContext的静态初始化就会执行。
初始化所需的时间长度与 DbSet
声明并没有真正关联,而是与 DbContext
需要注意的实体总数有关.即使您有 100 个“top-level”实体并为它们定义了 DbSet
,如果这些实体展开以揭示与另外 1700 个实体的关系,那么这实际上与 1800 个 DbSet 的工作量相同。
限界上下文是一个将实体拆分为“上下文”的过程,其中每个 DbContext
服务于系统的一个关键区域。这既减少了每个 DbContext
需要了解的实体数量,加快了初始化速度,但它也有助于更好地组织代码以专注于实体,甚至是与该区域相关的基础数据的表示。实体可以在 DbContext
个实例之间共享,但您应该设法确保只有一个 DbContext
负责编写该实体。例如,您可以定义单独的 DbContext
实例来管理客户和管理订单。订单需要了解他们的客户,但 create/update 客户信息是 CustomerDbContext 的责任,而不是 OrderDbContext。一种选择是在 OrderDbContext 中使用类似于 CustomerSummary 实体的东西来映射订单上下文中客户的基本详细信息。理想情况下,DbContext 应该检查 SaveChanges 上的 inserted/updated/deleted 更改跟踪器中存在哪些实体类型,如果出现它们负责的实体类型以外的任何实体类型,则抛出异常。
通常归咎于大小的 DbContext 的典型性能杀手通常允许 DbContext 实例存在时间过长并跟踪太多实体。 DbContext 知道的实体越多,他们就越容易最终跟踪更多的实体,而开发人员没有意识到实例打开的时间太长。假设更大的上下文创建起来“更昂贵”,因此它打开和传递的时间更长 around/persisted 以避免感知成本,这会导致该实例逐渐被跟踪实例膨胀而导致性能成本。