【问题标题】:EF core 6 result doesn't match the databaseEF core 6 结果与数据库不匹配
【发布时间】:2022-11-07 23:16:14
【问题描述】:

我执行一个查询,但我并不总是得到相同的结果。

我用断点一步一步地执行了下面的sn-p。 此代码的用例是等到某个进程不再忙,然后再继续执行。

  • .NET 6.0
  • EF 核心 6.0.4
string slug = "abc";
Entity entity = await _resource.GetQueryable()
    .Where(x => x.Slug == slug)
    .FirstOrDefaultAsync();
// entity.IsBusy is true

int retries = 0;
while(entity.IsBusy)
{
    if (retries > 10)
    {
        throw new SyncIsBusyException();
    }
    retries++;

    // Now I manually execute an SQL query on the database.
    // update Entities set IsBusy = 'false'

    Thread.Sleep(3000);
    entity = await _resource.GetQueryable()
        .Where(x => x.Slug == slug)
        .FirstOrDefaultAsync();
    // entity.IsBusy is still true (not in the DB)

    string test = await _resource.GetQueryable()
        .Where(x => x.Slug == slug)
        .Select(x => x.IsBusy)
        .FirstOrDefaultAsync();
    // test is false (which is correct)

    // test if creating a new variable changes things
    var test1 = await _resource.GetQueryable()
        .Where(x => x.Slug == slug)
        .FirstOrDefaultAsync();
    // test1.IsBusy is true (which is again incorrect)
}

资源:

public virtual IQueryable<TEntity> GetQueryable()
{
    var queryable = _dbContext.Set<TEntity>().AsQueryable();
    return queryable;
}

它看起来像某种缓存,但我没有任何设置。我还可以在控制台中看到正在执行的 SQL 查询。当我在数据库上手动执行这个生成的 SQL 查询时,我得到了正确的预期结果(IsBusy false)。 我可以通过在while 上方添加bool isBusy = entity.IsBusy; 然后使用它来修复此错误。但我仍然想知道这里的根本问题。

【问题讨论】:

    标签: c# .net entity-framework-core .net-6.0 ef-core-6.0


    【解决方案1】:

    Slug 是您实体的主键吗?

    更改跟踪器将通过其主键缓存实体,除非您清除本地缓存 (dbContext.ChangeTracker.Clear()) 或首先使用.AsNoTracking() 查询它。

    后者确实阻止了对实体的更新。

    Select 查询投影实体的子集,因此查询是对商店执行。

    【讨论】:

    • slug 不是主键,但 AsNoTracking() 在应用于 while 内的第一个查询时解决了该问题。我不能使用它,因为我稍后会更新它。
    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多