如何结合Find()和AsNoTracking()?

Nea*_*hal 18 c# entity-framework

如何在对EF上下文进行查询时结合Find()使用AsNoTracking()以防止跟踪返回的对象.这是我不能做的

 _context.Set<Entity>().AsNoTracking().Find(id);
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?我使用EF版本6.

注意:我不想使用SingleOrDefault(),或Where.我只是不能,因为参数Id是通用的,它是一个struct,我不能==在这种情况下应用泛型运算符.

Der*_*ked 18

因此,不要使用AsNoTracking()您可以做的事情Find(),然后将其从上下文中分离出来.我相信这会给你带来与AsNoTracking()获得实体跟踪的额外开销相同的结果.有关更多信息,请参阅EntityState.

var entity = Context.Set<T>().Find(id);
Context.Entry(entity).State = EntityState.Detached;
return entity;
Run Code Online (Sandbox Code Playgroud)

编辑:这有一些潜在的问题,如果上下文没有加载一些关系,那么这些导航属性将无法工作,你会感到困惑和沮丧为什么一切都返回null!有关详细信息,请参阅/sf/answers/724022211/.就目前在那些存储库而言,我正在覆盖FindNoTracking()我需要的存储库中的方法.

  • 如果您阅读有关该问题的注释,那么在使用泛型时,Rosedi Kasim 的答案是不够的,因为您不能使用 == 运算符,因此它甚至无法编译。 (2认同)

JR *_*rez 9

早在 2015 年,官方就提出了包含该功能的请求,即结合 Find() 和 AsNoTracking()。提出这个论点后,该问题立即关闭:

AsNoTracking并没有真正意义,Find因为 find 的关键功能之一是,如果实体已经在内存中,它将返回实体的已跟踪版本,而无需访问数据库。如果您想通过键加载实体而不跟踪它,请使用Single

因此,您可以替换:

_context.Set<Entity>().AsNoTracking().Find(id); // Invalid
Run Code Online (Sandbox Code Playgroud)

像这样的东西:

_context.Set<Entity>().AsNoTracking().Single(e => e.Id == id);
Run Code Online (Sandbox Code Playgroud)


Ros*_*sim 8

<context>.<Entity>.AsNoTracking().Where(s => s.Id == id);
Run Code Online (Sandbox Code Playgroud)

Find()没有意义,AsNoTracking()因为Find它应该能够返回被跟踪的实体而无需进入数据库..你唯一的选择AsNoTrackingWhere或者First或者Single...

  • 不能使用它,因为`Id`是通用的,我不能使用运算符`==`with generics :) (2认同)