应该在哪里应用AsNoTracking?

问题描述:

我正在将查询从Linq-to-sql迁移到EF。为了使禁用跟踪更难以忘记,在Linq-To-Sql中,我编写了一个ConfigureForQuery包装器函数,它简单地将ObjectTrackingEnabled设置为false。
我想继续使用类似的策略,但根据我目前收集的信息,没有跟踪的全局设置不可用。我想就如何最好地解决我现有的问题提出意见。部分代码:应该在哪里应用AsNoTracking?

public class A { 
    public int P1 { get; set; } 
    public int P2 { get; set; } 
} 
public class B { 
    public int P3 { get; set; } 
    public int P4 { get; set; } 
} 
public class MyDbContext : DbContext { 
    public IDbSet<A> As { get; set; } 
    public IDbSet<B> Bs { get; set; } 
} 

// scenario 1: returning IQueryable of T where IDbSet<T> is defined in a DbContext 
public IQueryable<A> Get() 
{ 
    var query = 
     from a in db.As 
     join b in db.Bs 
      on a.P1 equals b.P3 
     where b.P4 > 50 
     select a; 
    return query; 
} 

问题1:在哪里以及如何应用AsNoTracking?
Q2:在这种情况下,我是否需要将AsNoTracking应用于Bs?

// scenario 2: returning IQueryable of T where IDbSet<T> is NOT defined in a DbContext 
public class C { 
    public int P1 { get; set; } 
    public int P4 { get; set; } 
} 
public IQueryable<C> Get() 
{ 
    var query = 
     from a in db.As 
     join b in db.Bs 
      on a.P1 equals b.P3 
     where b.P4 > 50 
     select C { P1 = a.P1, P4 = b.P4}; 
    return query; 
} 

问题3:在这种情况下,我需要使用AsNoTracking吗?

感谢您的帮助。

+0

看到这个:http://stackoverflow.com/questions/12726878/global-setting-for-asnotracking – 2014-10-22 11:26:46

+0

@AlaaMasoud我编辑的问题。谢谢。 – 2014-10-22 13:49:32

在第一种情况下,你可以简单地应用AsNoTracking到查询结果:

public IQueryable<A> Get() { 
    var query = 
    from a in db.As 
    join b in db.Bs 
     on a.P1 equals b.P3 
    where b.P4 > 50 
    select a; 

    return query.AsNoTracking(); 
} 

在第二个方案,因为你正在返回的东西不在的DbContext那么它不会跟踪反正所以你不要不需要做任何事情。

您可以在查询后查看更改跟踪器,以查看正在跟踪的内容以及未跟踪的内容。

var tc = db.ChangeTracker.Entries().Count(); 
+0

记得使用System.Data.Entity添加;为AsNoTracking()扩展提供IQueryable Stewart 2016-02-02 22:55:23