在以下情况下,由于方法调用而嵌套了两个DbContext:
public void Method_A() {
using (var db = new SomeDbContext()) {
//...do some work here
Method_B();
//...do some more work here
}
}
public void Method_B() {
using (var db = new SomeDbContext()) {
//...do some work
}
}
题:
public void Method_A() {
using (var db = new SomeDbContext()) {
//...do some work here
}
Method_B();
using (var db = new SomeDbContext()) {
//...do some more work here
}
}
谢谢。
最佳答案
您的DbContext
派生类实际上在这里为您管理了至少三件事:
Entity Framework 通常缓存元数据(项目1),以便所有上下文实例(或至少使用相同连接字符串的所有实例)共享元数据。因此,在此无需担心。
如其他注释中所述,您的代码导致使用两个数据库连接。这可能对您来说不是问题。
您还将最终获得两个客户端缓存(项目3)。如果您恰巧是从外部上下文中加载一个实体,然后再次从内部上下文中加载一个实体,则在内存中将有两个副本。这肯定会造成困惑,并可能导致细微的错误。这意味着,如果您不想使用共享上下文对象,那么您的选项2可能会比选项1更好。
如果您使用的是事务,则还有其他注意事项。具有多个数据库连接可能会导致将事务提升为分布式事务,这可能不是您想要的。由于您没有提及数据库事务,因此在此不再赘述。
那么,这离开了你呢?
如果您只是为了避免在代码中传递
DbContext
对象而使用此模式,那么使用可能会更好,因为重构MethodB
以便将上下文作为参数接收。有关应使用多长时间的上下文对象的问题反复出现。根据经验,可以为单个数据库操作或一系列相关的数据库操作创建新的上下文。 (例如,参见this blog post和this question。)(作为替代,您可以向接收现有连接的
DbContext
派生类中添加一个构造函数。然后,您可以在多个上下文之间共享相同的连接。)一种有用的模式是编写您自己的类,该类创建一个上下文对象并将其存储为私有(private)字段或属性。然后,使您的类实现
IDisposable
,并且其Dispose()
方法处置上下文对象。您的调用代码将消息通知类的实例,而不必担心上下文或连接。什么时候需要同时激活多个上下文?
当您需要编写多线程代码时,这可能会很有用。数据库连接不是线程安全的,因此您一次只能从一个线程访问一个连接(因此也只能访问一个EF上下文)。如果限制太严格,则需要多个连接(和上下文),每个线程一个。您可能会发现this很有趣。
关于entity-framework - 由于方法调用导致嵌套的DbContext- Entity Framework ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12913108/