Entity framework 实体框架中LINQ查询中AsNoTracking的范围

Entity framework 实体框架中LINQ查询中AsNoTracking的范围,entity-framework,Entity Framework,在实体框架中的LINQ查询中使用AsNoTracking方法时,是否应该对每个表或整个查询使用该方法,以便对整个查询禁用更改跟踪 1。针对整个查询 var query = (from t1 in db.Table1 from t2 in db.Table2.Where(o => t1.ConditionId == o.ConditionId) select t1).AsNoTracking() 2。针对每个表 var query = (fr

在实体框架中的LINQ查询中使用
AsNoTracking
方法时,是否应该对每个表或整个查询使用该方法,以便对整个查询禁用更改跟踪

1。针对整个查询

var query = (from t1 in db.Table1
            from t2 in db.Table2.Where(o => t1.ConditionId == o.ConditionId)
            select t1).AsNoTracking()
2。针对每个表

var query = (from t1 in db.Table1.AsNoTracking()
            from t2 in db.Table2.AsNoTracking().Where(o => t1.ConditionId == o.ConditionId)
            select t1)
我的意图是对整个查询禁用更改跟踪,但如果不是必需的话,我不想对每个表使用它

引用此方法文档中的查询对象:

此方法通过调用底层对象的AsNoTracking方法来工作 查询对象。如果基础查询对象没有 作为NotTracking方法,则调用此方法将不起任何作用


根据我刚刚做的一个测试,两个结果都是一样的。使用表级或QueryLevel作为notracking会导致没有实体被保存到tine ChangeTracker中。但无论哪种方式,表2中的实体都不会放在ChangeTracker中,正如您在WithToutasNotTracking测试中看到的那样

基于这样的假设,您确实在查询来自t1和t2的数据。我已经添加了一个测试,当我查询所有条目时,仍然会在查询中添加一个AsNoTracking,不会跟踪任何条目。但是,如果将AsNoTracking()直接放在表1上,则不会跟踪表1和表2中的实体

    [TestMethod]
    public void QueryLevelAsNoTracking()
    {
        using (var context = new DbContext())
        {
            var query = (from t1 in context.Table1
                         from t2 in context.Table2.Where(o => t1.ConditionId == o.ConditionId)
                         select t1).AsNoTracking();

            var list = query.ToList();
            Assert.AreEqual(0, context.ChangeTracker.Entries().Count());
        }
    }

    [TestMethod]
    public void TableLevelAsNoTracking()
    {
        using (var context = new DbContext())
        {
            var query = (from t1 in context.Table1.AsNoTracking()
                         from t2 in context.Table2.Where(o => t1.ConditionId == o.ConditionId)
                         select t1);

            var list = query.ToList();
            Assert.AreEqual(0, context.ChangeTracker.Entries().Count());
        }
    }

    [TestMethod]
    public void WithtoutAsNoTracking()
    {
        using (var context = new DbContext())
        {
            var query = (from t1 in context.Table1
                         from t2 in context.Table2.Where(o => t1.ConditionId == o.ConditionId)
                         select t1);

            var list = query.ToList();
            Assert.AreEqual(7, context.ChangeTracker.Entries().Count(x => x.Entity is Table1));
            Assert.AreEqual(0, context.ChangeTracker.Entries().Count(x => x.Entity is Table2));
        }
    }


    [TestMethod]
    public void QueryLevelAsNoTracking_SelectAllData()
    {
        using (var context = new DbContext())
        {
            var query = (from t1 in context.Table1
                         from t2 in context.Table2.Where(o => t1.ConditionId == o.ConditionId)
                         select new
                                    {
                                            t1,
                                            t2
                                    }).AsNoTracking();

            var list = query.ToList();
            Assert.AreEqual(0, context.ChangeTracker.Entries().Count());
        }
    }

    [TestMethod]
    public void Table1AsNoTracking_SelectAllData()
    {
        using (var context = new DbContext())
        {
            var query = (from t1 in context.Table1.AsNoTracking()
                         from t2 in context.Table2.Where(o => t1.ConditionId == o.ConditionId)
                         select new
                         {
                             t1,
                             t2
                         });

            var list = query.ToList();
            Assert.AreEqual(0, context.ChangeTracker.Entries().Count(x => x.Entity is Table1));
            Assert.AreEqual(0, context.ChangeTracker.Entries().Count(x => x.Entity is Table2));
        }
    }
此外,我还从join子句的表2中删除了AsNoTracking,因为它导致了一个异常

System.ArgumentException:方法“System.Data.Entity.Infrastructure.DbQuery
1[DataModel.Table12 AsNotTracking()”在类型“System.Data.Entity.Infrastructure.DbQuery
1[DataModel.Table2]”的实例中无法调用“System.Data.Objects.ObjectQuery`1[DataModel.Table2]”


这是一个全面的答案。谢谢。所以当你进行连接时,AsNoTracking()是无用的?@Giox完全正确。AsNoTracking()不会影响连接