gpt4 book ai didi

entity-framework - 由于方法调用而嵌套 DbContext - Entity Framework

转载 作者:行者123 更新时间:2023-12-03 08:48:47 24 4
gpt4 key购买 nike

在以下情况下,由于方法调用而嵌套了两个 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
}
}

问题:
  • 这种嵌套会导致任何问题吗? (正确的 DbContext 会在正确的时间处理吗?)
  • 这种嵌套是否被认为是不好的做法,是否应该将 Method_A 重构为:
    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派生类实际上在这里为您管理至少三件事:

  • 描述数据库和实体模型的元数据,
  • 底层数据库连接和
  • 使用上下文加载的实体的客户端“缓存”,用于更改跟踪、关系修复等(请注意,尽管我将其称为“缓存”是因为需要更好的词,但这通常是短暂的,只是为了支持EF 功能。如果适用,它不能替代应用程序中的适当缓存。)

  • Entity Framework 通常缓存元数据(第 1 项),以便所有上下文实例(或至少使用相同连接字符串的所有实例)共享它。因此,在这里,您无需担心。

    正如其他评论中提到的,您的代码导致使用两个数据库连接。这对您来说可能是也可能不是问题。

    您最终还会得到两个客户端缓存(第 3 项)。如果您碰巧从外部上下文加载了一个实体,然后再次从内部上下文加载,您将在内存中拥有它的两个副本。这肯定会令人困惑,并可能导致细微的错误。这意味着,如果您不想使用共享上下文对象,那么 您的选项 2 可能比选项 1 更好。

    如果您使用 交易 ,还有进一步的考虑。拥有多个数据库连接可能会导致事务被提升为分布式事务,这可能不是您想要的。由于您没有提及数据库事务,因此我不会在这里进一步讨论。

    那么,这会让你在哪里?

    如果您使用此模式只是为了避免传递 DbContext代码中的对象,然后 重构 MethodB 可能会更好接收上下文作为参数 .应该反复出现多长生命周期的上下文对象的问题。根据经验,为单个数据库操作或一系列相关数据库操作创建新上下文。 (例如,参见 this blog postthis question。)

    (作为替代方案,您可以向您的 DbContext 派生类添加一个构造函数来接收现有连接。然后您可以在多个上下文之间共享相同的连接。)

    一种有用的模式是编写自己的类来创建上下文对象并将其存储为私有(private)字段或属性。然后你让你的类(class)实现 IDisposable及其 Dispose()方法处理上下文对象。您的调用代码会更新您的类的一个实例,并且根本不必担心上下文或连接。

    您何时可能需要同时激活多个上下文?

    当您需要编写多线程代码时,这会很有用。数据库连接不是线程安全的,因此您一次只能从一个线程访问一个连接(因此也是一个 EF 上下文)。如果这限制性太大,您需要多个连接(和上下文),每个线程一个。您可能会发现 this有趣的。

    关于entity-framework - 由于方法调用而嵌套 DbContext - Entity Framework ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12913108/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com