【问题标题】:How do I detach objects in Entity Framework Code First?如何在 Entity Framework Code First 中分离对象?
【发布时间】:2011-08-01 17:34:18
【问题描述】:

DbContext 上没有Detach(object entity)

我有能力先分离 EF 代码上的对象吗?

【问题讨论】:

    标签: entity-framework entity-framework-4.1 ef-code-first


    【解决方案1】:

    这是一个选项:

    dbContext.Entry(entity).State = EntityState.Detached;
    

    【讨论】:

    • 在检索返回 IQueryable 的对象时可以这样做吗?
    • @Lol 编码器:我不确定我是否理解正确,但entity 必须是属于您的模型类(Person、Customer、Order 等)的类型的物化对象。 )。您不能直接将 IQueryable 传递到 dbContext.Entry(...)。这是你的意思吗?
    • @EladBenda:这取决于。如果要分离已附加到上下文的对象,请将状态设置为 Detached。如果您想从数据库中加载实体而不将它们附加到上下文(无更改跟踪),请使用AsNoTracking
    • @kjbartel :这是预期的行为,因为实体与上下文没有链接。
    • @rcdmk 如果你在另一个答案中得到一个带有AsNoTracking 的实体,那么延迟加载仍然有效。这个方法不会。
    【解决方案2】:

    如果您想分离现有对象,请遵循@Slauma 的建议。如果您想加载对象而不跟踪更改,请使用:

    var data = context.MyEntities.AsNoTracking().Where(...).ToList();
    

    正如评论中提到的,这不会完全分离实体。它们仍然是附加的并且延迟加载工作,但实体没有被跟踪。例如,如果您只想加载实体以读取数据并且不打算修改它们,则应使用此选项。

    【讨论】:

    • @Ladislav:这确实可能是 Lol 编码器的意思。尽管我经常加载对象列表并立即处理上下文,但我从未使用和考虑过这种方法,例如using(ctx){ return ctx....ToList(); }。在这种情况下,使用AsNoTracking() 会很有意义,因为我会省去不必要地填充对象上下文。我想它可能会对性能和内存消耗有好处,尤其是对于大型列表,对吧?
    • @Slauma:是的,它具有性能优势。这就是为什么存在这种方法的原因。在 ObjectContext API 中使用这种方法有点复杂。
    • 这会禁用延迟加载吗?
    • 实际上这不会禁用延迟加载它只会禁用更改跟踪并提高性能=实体仍然附加。我是在回答这个问题后找到的,所以你应该将@Slauma 的问题标记为有效答案。
    • 这就是我想要的。我想要延迟加载和只修改分离实体的能力。
    【解决方案3】:

    之前的两个答案都提供了很好的说明,但是,这两个答案都可能使您仍然将实体加载到 EF 的上下文和/或其更改跟踪器中。

    当你改变小数据集时这不是问题,但当你改变大数据集时它会成为一个问题。 EF 会增加内存和资源的使用,这反过来会降低过程性能,因为它使用更多的数据/实体。

    其他两种方法都有效,但在这种情况下,Microsoft recommends 清理更改跟踪器而不是单独分离实体

    清除数据更改循环上的更改跟踪器(例如更改一大块数据)可以让您免于这个麻烦。

    context.ChangeTracker.Clear();
    

    这将从上下文中卸载/分离所有实体及其相关的 changeTracker 引用,因此请在 context.SaveChanges() 之后小心使用。

    【讨论】:

    • 两者都会让实体仍然加载到 EF 的变更跟踪器中——这不是真的。分离对象会将其从更改跟踪器中删除。如果实体是延迟加载代理,则它具有对上下文的引用,但这与附加到它不同(Ladislav 的措辞在这里有点含糊)。
    • 嗨 Gert,您可以通过快速测试来验证它。实体以分离状态保留在 ChangeTracker 中。类似于内存泄漏(但不幸的是设计..)。调用 Clear 命令会从 Context 中移除所有实例化的实体对象
    • 当然状态是分离的,还有什么?即使您创建了一个从未见过上下文的全新实体,它的状态也是分离的。这只是EF的说法:不知道这个,与它无关。另一种方法是在验证上下文之外的任何实体的状态时抛出异常。当然没有人想要那样。
    • 然而 EF 将它保留在内存中,就像内存泄漏一样分离
    • 那么请说明如何。你的说法没有任何依据。
    猜你喜欢
    • 1970-01-01
    • 2013-10-28
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    相关资源
    最近更新 更多