gpt4 book ai didi

entity-framework - Entity Framework 中LINQ查询中AsNoTracking的范围

转载 作者:行者123 更新时间:2023-12-03 10:14:34 25 4
gpt4 key购买 nike

在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 = (from t1 in db.Table1.AsNoTracking()
from t2 in db.Table2.AsNoTracking().Where(o => t1.ConditionId == o.ConditionId)
select t1)

我的意图是对整个查询禁用更改跟踪,但是如果不需要,则不想在每个表上使用它。

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

This method works by calling the AsNoTracking method of the underlying query object. If the underlying query object does not have a AsNoTracking method, then calling this method will do nothing.

最佳答案

根据测试,我刚刚得出的结果是相同的。使用Table Level或QueryLevel AsNoTracking不会导致将任何实体保留在常规ChangeTracker中。但是无论哪种方式,Table2中的实体都不会放在ChangeTracker中,正如您在WithtoutAsNoTracking测试中所看到的那样。

基于这样的假设,您确实在查询t1和t2中的数据。当我查询所有条目时仍然添加了一个测试,并向查询中添加了一个AsNoTracking,没有条目被跟踪。即使将AsNoTracking()直接放在table1上,也不会跟踪table1和table2中的实体。

    [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子句中的Table2中删除了AsNoTracking,因为它引起了异常。

System.ArgumentException: Method 'System.Data.Entity.Infrastructure.DbQuery1[DataModel.Table12 AsNoTracking()' declared on type 'System.Data.Entity.Infrastructure.DbQuery1[DataModel.Table2]' cannot be called with instance of type 'System.Data.Objects.ObjectQuery`1[DataModel.Table2]'

关于entity-framework - Entity Framework 中LINQ查询中AsNoTracking的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18231039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com