我有一个问题与SQLite数据库访问.我得到错误的数据返回.这是一个单一的应用程序运行作为一个“服务”,通过TCP/IP套接字客户端/服务器访问的工作站.这个应用程序做所有的数据库访问.“服务器”是使用.net 6.x和EF Core 6.x与SQLite.
我看到的是,我将从DB中获取以前的数据,而不是当前状态。
当我在上下文上使用linq时,如下所示:
Account account = custDB.Accounts.AsNoTracking()
.Where(a => a.AcctNo == accountNum)
.FirstOrDefault();
我会得到什么磁盘罚款,但在数据库更新后,我仍然得到相同的初始值。
我试着在我的Linq Select中使用.AsNoTracking(),每次我都在DB中获得当前数据。但是当我更新DB时,新数据不会写入DB,并且我没有抛出错误。
以下是序列:
- 使用linq查找记录:
Account account = custDB.Accounts.AsNoTracking()
.Where(a => a.AcctNo == accountNum)
.FirstOrDefault();
- 执行任务以更新返回的对象帐户
- 将更新的帐户对象传递到更新例程
private void UpdateAccountTable(Account account)
{
Account acct;
try
{
acct = custDB.Accounts.Where(a => a.ID == account.ID).Single();
}
catch (Exception ex)
{
throw new DbUpdateException(Message);
}
try
{
acct.AcctNo = account.AcctNo;
acct.Active = account.Active;
acct.Address1 = account.Address1;
acct.City = account.City;
acct.IsAPIAcct = account.IsAPIAcct;
acct.Name = account.Name;
acct.Phone = account.Phone;
acct.SerialNo = account.SerialNo;
acct.State = account.State;
acct.SWSIMID = account.SWSIMID;
acct.SWSIMPhrase = account.SWSIMPhrase;
acct.Zip = account.Zip;
acct.IsVerified = account.IsVerified;
acct.CleanHash = account.CleanHash;
acct.OverRideHash = account.OverRideHash;
acct.Zip4 = account.Zip4;
custDB.SaveChanges();
}
catch (Exception ex)
{
throw new DbUpdateException(Message);
}
}
没有抛出错误。结果是它在编程上看起来很好,但数据库永远不会用新值更新。
现在,如果我删除第一个select linq中的.asNoTracking(),数据库就会正确更新。
我做错了什么。
3条答案
按热度按时间tez616oj1#
EF Core使用change tracking执行DML,因此任何插入都会导致更改跟踪器中存在一些数据。更改跟踪器中存在的数据可能会导致返回陈旧数据(没有实际命中数据库或跳过MapAFAIK,also see this answer for some details)
DbContext
被设计成重量轻并且创建和丢弃成本相当低,通常的模式是每个请求/作用域有一个上下文示例(例如在ASP.NET Core中,通常每个HTTP请求都有一个)。在没有看到整个解决方案的情况下,很难说如何修改它会更好,因此它遵循此模式。如果由于重构量的原因,目前还不可能-您也可以通过ChangeTracker.Clear
(custDB.ChangeTracker.Clear();
)手动清除更改跟踪器,例如在每个SaveChanges
之后。hc2pp10m2#
AsNoTracking
用于不更改数据的查询。因此,调用SaveChanges
不会生效。https://entityframeworkcore.com/querying-data-asnotracking
由于不需要设置更改跟踪信息,因此不会快速执行任何跟踪查询。在只读方案中使用结果时,这很有用。
rqenqsqc3#
对于那些建议我做一个使用上下文,是的,这是问题。我在Open DB方法期间打开了上下文并保持打开状态。这是一个读取多次的类型表,很少写入。经过进一步测试,我发现我必须将上下文传递给我的UpdateAccountTable方法参数,否则数据库被“锁定”。现在我在预期时看到正确的更新,并正确地获取更新的数据。
谢谢大家。