当只有读操作时,将 DbContext 作为单例注入是否可以?
Is it ok to inject DbContext as singleton when there is only read operations?
我知道 DbContext
不是线程安全的,加上 DbContext
缓存数据,当多个事务试图 save/commit 将自己的更改写入数据库时,可能会导致数据不一致。因此,强烈建议根据请求注入它 (here)。但我遇到的情况是只存在读取操作(在独立的 class 库中)并且没有事务或 create/update/delete 操作。
我的问题是:在这种情况下将 DbContext
作为单例注入是否安全?
Entity Framework 开发人员明确表示 DbContext
对于对其执行的 任何 操作都不是线程安全的,而不仅仅是写入(添加、保存更改等)操作,如果你不想有一天花几天时间调试神秘的故障,你应该相信他们。
即使是读操作,EF 也可以对其非线程安全的内部结构执行 in-memory 写操作,您不能确定它在任何给定情况下都不会这样做。例如,从documentation开始,对查询返回的结果集进行处理:
If the query is a tracking query, EF checks if the data represents an
entity already in the change tracker for the context instance
因此,如果查询正在跟踪查询 - 它会检查当前实例的更改跟踪器,以查找具有相同键的此类已经存在的实体,这意味着如果此类实体不存在 - 它会将其放入更改跟踪器中。这是写操作,所以不安全。
你可以说,好吧,那我就用AsNoTracking()
。但是 here 是另一个问题,关于并发 AsNoTracking
查询 - EF 甚至不允许您执行它们。库维护者说:
Concurrent use of the same DbContext is not possible - and not just
for tracked queries. Specifically, a DbContext has an underlying
DbConnection to the database, which cannot be used concurrently. There
are other various components at work under the hood which don't
support multithreading.
However, there's nothing wrong with instantiating several DbContexts
and executing queries on them - whether tracking or non-tracking. That
should get you the behavior you're looking for. If you run into any
further issues don't hesitate to post back.
因此存在未记录的内部组件,这些组件不是线程安全的,您无法确定在多个线程中对 DbContext
执行 任何操作 时您不会打这样的组件。
我知道 DbContext
不是线程安全的,加上 DbContext
缓存数据,当多个事务试图 save/commit 将自己的更改写入数据库时,可能会导致数据不一致。因此,强烈建议根据请求注入它 (here)。但我遇到的情况是只存在读取操作(在独立的 class 库中)并且没有事务或 create/update/delete 操作。
我的问题是:在这种情况下将 DbContext
作为单例注入是否安全?
Entity Framework 开发人员明确表示 DbContext
对于对其执行的 任何 操作都不是线程安全的,而不仅仅是写入(添加、保存更改等)操作,如果你不想有一天花几天时间调试神秘的故障,你应该相信他们。
即使是读操作,EF 也可以对其非线程安全的内部结构执行 in-memory 写操作,您不能确定它在任何给定情况下都不会这样做。例如,从documentation开始,对查询返回的结果集进行处理:
If the query is a tracking query, EF checks if the data represents an entity already in the change tracker for the context instance
因此,如果查询正在跟踪查询 - 它会检查当前实例的更改跟踪器,以查找具有相同键的此类已经存在的实体,这意味着如果此类实体不存在 - 它会将其放入更改跟踪器中。这是写操作,所以不安全。
你可以说,好吧,那我就用AsNoTracking()
。但是 here 是另一个问题,关于并发 AsNoTracking
查询 - EF 甚至不允许您执行它们。库维护者说:
Concurrent use of the same DbContext is not possible - and not just for tracked queries. Specifically, a DbContext has an underlying DbConnection to the database, which cannot be used concurrently. There are other various components at work under the hood which don't support multithreading.
However, there's nothing wrong with instantiating several DbContexts and executing queries on them - whether tracking or non-tracking. That should get you the behavior you're looking for. If you run into any further issues don't hesitate to post back.
因此存在未记录的内部组件,这些组件不是线程安全的,您无法确定在多个线程中对 DbContext
执行 任何操作 时您不会打这样的组件。