我在访问 SQLite 数据库时遇到问题。我得到返回的错误数据。这是作为“服务”运行的单个应用程序,站点通过 TCP/IP 套接字客户端/服务器访问该应用程序。这个应用程序完成所有的数据库访问。 “服务器”使用 .net 6.x 和 EF Core 6.x 以及 SQLite。
我看到的是我将从数据库中获取以前的数据,而不是当前状态。
当我在如下上下文中使用 linq 时:
Account account = custDB.Accounts.AsNoTracking()
.Where(a => a.AcctNo == accountNum)
.FirstOrDefault();
我会得到磁盘上的内容,但在数据库更新后,我仍然得到相同的初始值。
我尝试在我的 Linq Select 中使用 .AsNoTracking() 并且我每次都在数据库中获取当前数据。但是当我更新数据库时,新数据没有写入数据库并且我没有抛出任何错误。
顺序如下:
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(),数据库就会正确更新。
我做错了什么。
AsNoTracking
用于不更改数据的查询。所以调用SaveChanges
不生效
https://entityframeworkcore.com/querying-data-asnotracking
没有跟踪查询快速执行,因为不需要设置更改跟踪信息。当结果用于只读场景时,它很有用。
EF Core 使用 change tracking 执行 DML,因此任何插入都会导致一些数据出现在 change tracker 中。更改跟踪器中存在的数据可能导致返回过时的数据(没有实际访问数据库或跳过映射 AFAIK,另请参阅此答案以获取一些详细信息)
DbContext
被设计为轻量级且创建和丢弃的成本非常低,通常的模式是每个请求/范围有一个上下文实例(例如,在 ASP.NET Core 中,您通常每个 HTTP 请求都有一个)。在没有看到整个解决方案的情况下,很难说出如何修改它以使其遵循这种模式会更好。如果由于重构量目前无法实现 - 您还可以通过 ChangeTracker.Clear
(custDB.ChangeTracker.Clear();
) 手动清除更改跟踪器,例如在每次 SaveChanges
. 之后