首页 > 解决方案 > 在将 DBSet 转换为列表之前,实体框架不会看到数据库中的数据

问题描述

我将控制器的索引 API 定义如下:

[HttpGet]
public IEnumerable<Blog> GetDatas()
{
    return _context.Blogs;
}

即使数据库包含许多blogs,这也总是返回空。但是,当我仅出于测试原因执行以下操作时,实体框架设法查看数据并可以返回blog数据库中的所有 s:

[HttpGet]
public IEnumerable<Blog> GetDatas()
{
    var blogs = _context.blogs.ToList();
    return _context.Blogs;
}

有什么想法吗?

(可能与我的其他未回答的问题有关)。

更新 1

避免混淆 LINQ 中的延迟执行;我尝试了以下两种方法,并且没有使用这两种方法,返回的 json 对象包含数据库中已有的信息。换句话说,序列化对象不反映数据库中持久化的实体。我认为这些方法会触发 LINQ 查询的执行,对吗?

// Method 1:
[HttpGet]
public async Task<ActionResult<IEnumerable<Blog>>> GetDatas()
{
    return await _context.Blogs.ToListAsync().ConfigureAwait(false);
}

// Method 2:
[HttpGet]
public IEnumerable<Blog> GetDatas()
{
    return _context.Blogs.ToList();
}

标签: c#sql-serverentity-frameworkasp.net-coreentity-framework-core

解决方案


正如丹尼尔所说,这是设计使然。请参阅LINQ 中的延迟执行有什么好处?用于扩展讨论,但本质上是在使用数据时加载数据,而不是在请求时加载。您可以看到它为空的唯一方法是在调试器中;您的运行时代码不会这样看,因为一旦您尝试找出第一个表单是否为空,它将填充数据,此时(使用点)无关紧要空到那个点 - 没有任何东西使用它来确定它是空的还是满的

想想有点像薛定谔的猫

这实际上很有帮助:

var w = worldPopulation.Where(e => e.Gender = Gender.Male)

if(name!=null)
  w=w.Where(e=>e.Name == name)

第一个查询,如果它立即运行,可能会看到 35 亿个结果从您的数据库下载到您的客户端(与服务器相比是低规格的机器),然后名称过滤器会将其减少到几百万。首先,最好只通过非常慢的网络将几百万下载到您的缓慢,低规格的机器中......对吗?

仅在您实际请求数据时才运行查询的一个好处是,您最终真正知道您需要数据。到那时你可能从来不需要它,所以下载它会浪费资源


推荐阅读