linq SQLIte和EF6核心跟踪数据,数据查找失败

alen0pnh  于 2023-04-09  发布在  SQLite
关注(0)|答案(3)|浏览(166)

我有一个问题与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(),数据库就会正确更新。
我做错了什么。

tez616oj

tez616oj1#

EF Core使用change tracking执行DML,因此任何插入都会导致更改跟踪器中存在一些数据。更改跟踪器中存在的数据可能会导致返回陈旧数据(没有实际命中数据库或跳过MapAFAIK,also see this answer for some details
DbContext被设计成重量轻并且创建和丢弃成本相当低,通常的模式是每个请求/作用域有一个上下文示例(例如在ASP.NET Core中,通常每个HTTP请求都有一个)。在没有看到整个解决方案的情况下,很难说如何修改它会更好,因此它遵循此模式。如果由于重构量的原因,目前还不可能-您也可以通过ChangeTracker.ClearcustDB.ChangeTracker.Clear();)手动清除更改跟踪器,例如在每个SaveChanges之后。

hc2pp10m

hc2pp10m2#

AsNoTracking用于不更改数据的查询。因此,调用SaveChanges不会生效。
https://entityframeworkcore.com/querying-data-asnotracking
由于不需要设置更改跟踪信息,因此不会快速执行任何跟踪查询。在只读方案中使用结果时,这很有用。

rqenqsqc

rqenqsqc3#

对于那些建议我做一个使用上下文,是的,这是问题。我在Open DB方法期间打开了上下文并保持打开状态。这是一个读取多次的类型表,很少写入。经过进一步测试,我发现我必须将上下文传递给我的UpdateAccountTable方法参数,否则数据库被“锁定”。现在我在预期时看到正确的更新,并正确地获取更新的数据。

private void UpdateAccountTable(PostalCustDB custDB, Account account) {...}

谢谢大家。

相关问题