如何在Entity Framework Code First中分离对象?

Sha*_*ean 136 entity-framework ef-code-first entity-framework-4.1

没有Detach(object entity)DbContext.

我是否能够首先在EF代码上分离对象?

Sla*_*uma 227

这是一个选项:

dbContext.Entry(entity).State = EntityState.Detached;
Run Code Online (Sandbox Code Playgroud)

  • @EladBenda:这取决于.如果要分离已附加到上下文的对象,请将状态设置为"已分离".如果要从数据库加载实体而不将它们完全附加到上下文(无更改跟踪),请使用`AsNoTracking`. (8认同)
  • @kjbartel:这是预期的行为,因为实体没有与上下文的链接. (4认同)
  • 我可以在检索返回IQueryable的对象时执行此操作吗? (3认同)
  • @rcdmk 如果你得到一个像另一个答案中那样带有 `AsNoTracking` 的实体,那么延迟加载仍然有效。这个方法不会。 (2认同)

Lad*_*nka 145

如果你想分离现有的对象,请按照@Slauma的建议.如果要在不跟踪更改的情况下加载对象,请使用:

var data = context.MyEntities.AsNoTracking().Where(...).ToList();
Run Code Online (Sandbox Code Playgroud)

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

  • @Ladislav:这确实可能是Lol编码器的意思.我从来没有使用过,并认为这个方法虽然我经常加载对象列表,并在一次处置的背景下,像`使用(CTX){回报CTX .... ToList(); }`.在这种情况下,使用`AsNoTracking()`会有很大意义,因为我会不必要地保存填充对象上下文.我想它可能会有一个性能和内存消耗的好处,特别是对于大型列表,对吧? (3认同)
  • 实际上这不会禁用延迟加载它只会禁用更改跟踪并提高性能=实体仍然附加.我在回答这个问题之后找到了它,所以你应该将@ Slauma的一个标记为有效答案. (3认同)
  • 这会禁用延迟加载吗? (2认同)

The*_*bio 14

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

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

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

清除数据更改循环(例如更改一块数据)上的更改跟踪器可以使您免遭此麻烦。

context.ChangeTracker.Clear();
Run Code Online (Sandbox Code Playgroud)

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

  • 感谢@TheFabio - 这解决了在 EF 中批量插入非常大的图形时的巨大性能问题。为了解决这个问题,我在保存每个实体后使用了你的行,性能的提高和内存使用的改进非常棒。谢谢! (2认同)