直接从数据库返回 IEnumerable 或之前使用 ToListAsync

2024-04-21

当直接从数据库提供 IEnumerable 时,控制器如何工作?哪个代码更正确、更优化?假设数据库非常慢并且正在进行其他操作。

这个示例非常简单,因此执行时间可能没有足够的差异,但我正在尝试学习最佳实践。

#1

public Task<Application[]> Find(Expression<Func<Application, bool>> predicate)
{
    return DatabaseContext.Applications
        .Where(predicate)
        .ToArrayAsync();
}

...

public Task<Application[]> Find(...)
{
    return ApplicationService.Find(...);
}

#2

public Task<List<Application>> Find(Expression<Func<Application, bool>> predicate)
{
    return DatabaseContext.Applications
        .Where(predicate)
        .ToListAsync();
}

...

public async Task<IActionResult> Find(...)
{
    var applications = await ApplicationService.Find(...)
    return Ok(applications);
}

#3

public IEnumerable<Application> Find(Expression<Func<Application, bool>> predicate)
{
    return DatabaseContext.Applications;
}

...

public IActionResult<IEnumerable<Application>> Find(...)
{
    var applications = ApplicationService.Find(...);
    return Ok(applications);
}

当直接从数据库提供 IEnumerable 时,控制器如何工作?

(By IEnumerable我假设你的意思是直接返回一个未执行的IQueryable从你的DbContext)

他们不这样做,你也不应该这样做- 这是因为未执行IQueryable不代表加载的数据 - 当它执行时,它只能从打开的数据库连接加载数据 - 这需要一个活动且有效的DbContext.

...所以如果DbContext被处置,那么IQueryable不能被执行。

如果您创建DbContext在控制器动作内部并渲染IQueryable在您看来或返回它ObjectResponse(对于 Web API)那么它总是会失败:

public IActionResult GetPeople()
{
    // WARNING: NEVER DO THIS!
    using( MyDbContext db = new MyDbContext( GetConnectionString() ) )
    {
        return this.Ok( db.People.Where( p => p.Name == "John Smith" ) );

        // or:

        return this.View( model: db.People.Where( p => p.Name == "John Smith" ) );
    }
}

请记住.Ok() and this.View()不会触发视图的评估或向客户端发送对象响应 - 相反,它会导致控制器操作首先结束,然后将数据传递到 ASP.NET 管道中的下一步(即视图)。请记住:视图在控制器操作完成后执行。

如果您使用依赖注入来准备好您的实例DbContext在控制器中,结果不太可预测:IQueryable操作方法返回后仍然可以进行评估,因为DbContext在控制器被处置之后才会被处置,这通常是after视图已渲染,但是您仍然不应该这样做,因为您的IQueryable仍然可能会传递给某个比您的 Controller 类的生命周期更长的进程,这会导致失败。您还应该避免它,因为视图被设计为快速同步渲染 - 外部数据库或 IO 调用会破坏该设计。

(无论如何,您都不应该使用实体框架实体对象作为根 ViewModel,但这是另一个讨论)。

如果你总是使用async操作于DbContext (e.g. ToListAsync(), ToDictionaryAsync等 - 因为它们返回一个Task<List<T>> or TaskDictionary<TKey,TValue>>分别 - 这需要一个await默认情况下,编译器将阻止您在视图或对象结果中执行此操作(您can have await在视图中,但这是不可取的,并且需要在某处设置一些设置)。

简而言之,始终这样做:

public async Task<IActionResult> GetPeople()
{
    using( MyDbContext db = new MyDbContext( GetConnectionString() ) )
    {
        List<Person> list = await db.People
            .Where( p => p.Name == "John Smith" )
            .ToListAsync();

        // WebAPI:
        return this.Ok( list ); // returning an evaluated list, loaded into memory. (Make sure Lazy Navigation Properties are disabled too)

        // MVC:
        PeopleListViewModel vm = new PeopleListViewModel(); // in MVC always use a custom class for root view-models so you're not accepting nor returning Entity Framework entity types directly
        vm.List = list;

        return this.View( vm );
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

直接从数据库返回 IEnumerable 或之前使用 ToListAsync 的相关文章

  • 具有不同大小结构的结构数组的 malloc()

    如果每个结构都包含一个大小不同的字符串数组 那么如何正确地 malloc 一个结构数组 因此每个结构可能有不同的大小 并且不可能 realloc 结构体数量 sizeof 结构体名称 after malloc 初始大小 sizeof 结构名
  • Subversion 和 Visual Studio 项目的最佳实践

    我最近开始在 Visual Studio 中处理各种 C 项目 作为大型系统计划的一部分 该系统将用于替换我们当前的系统 该系统是由用 C 和 Perl 编写的各种程序和脚本拼凑而成的 我现在正在进行的项目已经达到了颠覆的临界点 我想知道什
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • 如何尝试/捕获所有异常

    我正在完成由其他人启动的 UWP 应用程序 该应用程序经常崩溃 我总是陷入困境应用程序 at if global System Diagnostics Debugger IsAttached global System Diagnostic
  • 从 C 结构生成 C# 结构

    我有几十个 C 结构 我需要在 C 中使用它们 典型的 C 结构如下所示 typedef struct UM EVENT ULONG32 Id ULONG32 Orgin ULONG32 OperationType ULONG32 Size
  • 如何创建用于 QML 的通用对象模型?

    我想知道是否有任何宏或方法如何将 Qt 模型注册为 QObject 的属性 例如 我有AnimalModel http doc qt io qt 5 qtquick modelviewsdata cppmodels html qabstra
  • 对 boost 库的依赖项没有完整路径

    我已经成功构建了动态库 依赖于使用自定义前缀构建和安装的 boost 库 b2 install prefix PREFIX 然而 当我跑步时otool L在我的库中 我得到如下输出 libboost regex dylib compatib
  • 将带有 glut 的点击坐标添加到向量链接列表中

    我想创建一个向量链接列表 并在 GLUT 库的帮助下获取点击的位置并将它们附加到链接列表中 这些是我写的结构 typedef struct vector int x int y Vector typedef struct VectorLis
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • C# 委托责任链

    为了我的理解目的 我实现了责任链模式 Abstract Base Type public abstract class CustomerServiceDesk protected CustomerServiceDesk nextHandle
  • 分配器感知容器和propagate_on_container_swap

    The std allocator traits模板定义了一些常量 例如propagate on container copy move assign让其他容器知道它们是否应该在复制或移动操作期间复制第二个容器的分配器 我们还有propag
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • 0-1背包算法

    以下 0 1 背包问题是否可解 浮动 正值和 浮动 权重 可以是正数或负数 背包的 浮动 容量 gt 0 我平均有 这是一个相对简单的二进制程序 我建议用蛮力进行修剪 如果任何时候你超过了允许的重量 你不需要尝试其他物品的组合 你可以丢弃整
  • 使用 iTextSharp 5.3.3 和 USB 令牌签署 PDF

    我是 iTextSharp 和 StackOverFlow 的新手 我正在尝试使用外部 USB 令牌在 C 中签署 PDF 我尝试使用从互联网上挖掘的以下代码 Org BouncyCastle X509 X509CertificatePar
  • 从 Delphi 调用 C# dll

    我用单一方法编写了 Net 3 5 dll 由Delphi exe调用 不幸的是它不起作用 步骤 1 使用以下代码创建 C 3 5 dll public class MyDllClass public static int MyDllMet
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • 类中不允许使用不完整类型,但类模板中允许使用不完整类型

    以下为无效代码 struct foo struct bar bar x error field x has incomplete type struct bar int value 42 int main return foo x valu
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率

随机推荐

  • 使用 Twitter Bootstrap 的水平形式内的普通(垂直)形式

    我想要一个在第一层具有水平布局的表单 但是在一行内可以有一个 内联 表单 我想要一个垂直 默认 布局 有没有一种简单的方法可以实现这一目标 Note form inline没有做我正在寻找的事情 因为它没有将内部标签放在输入的顶部 到目前为
  • Java 中是否有与 StringWriter 等效但内部带有 StringBuilder 的东西?

    我注意到 StringWriter 在内部使用 StringBuffer 但是 如果您不需要同步开销 是否有与 StringWriter 等效的内部使用 StringBuilder 的方法 如果你恰好使用 Apache Commons IO
  • 允许 Rust 格式中未使用的命名参数!() 系列

    Given format red reset text red RED blue BLUE reset RESET 编译器退出并出现错误 error named argument never used gt example rs 1 47
  • 提取后视频帧是颠倒的

    我的问题是 当我使用 opencv 将视频提取到帧中时 有时我得到的帧会翻转 这在我的机器 窗口 和 VM ubuntu 上都发生过 但是我测试的一些视频 帧不翻转 所以 我想知道应该在我的代码中更改 添加哪些因素或哪些内容 以使提取内容无
  • WebSocket 握手:意外响应代码:404

    正在编写我的第一个 websocket 程序并且正在得到 WebSocket 握手 意外响应代码 404 加载网页时出错 我使用的是 JDK 1 7 和 jboss 8 wildfly8 0 有人可以帮忙吗 window onload in
  • 通过代码更改 Vaadin 7 中的主题

    我正在 Vaadin 7 中做一个项目 我需要更改页面的主题 在 Vaadin 6 中 有一个名为 setTheme 的函数 这样我就可以在代码中的任何位置使用该函数更改主题 但是 在 Vaadin 7 中 我找不到类似的东西 我知道会有办
  • SLES Apache Solr start.jar,无法访问 jarfile

    我在启动 Apache Solr 搜索时遇到一些问题 在我的 SLES 11 64 位服务器上安装 java 7 后 我将 solr 3 6 1 解压到 srv apache solr 3 6 0 之后我想启动该软件 但是当我尝试时 jav
  • 如何解决此错误消息:错误:virtualenvwrapper 无法在路径中找到 virtualenv?

    我正在尝试在 Mac 上安装 Python Goose 我运行的是 OSX 10 9 3 安装 Goose 的第一步是 mkvirtualenv no site packages goose 但是 当我运行此命令时 我收到以下错误消息 错误
  • Xcode在哪里打开快速搜索?

    我不知道如何让它索引我的项目文件 快速打开应该搜索任何open项目 曾经有一个路径首选项 但我相信它在 3 1 中被删除了
  • 交换数组中的奇数和偶数

    我在这个网站上看到了这段代码 它使用一种方法对数组进行排序 偶数在前面 奇数在数组后面 我想知道你是否可以做同样的事情 除了先出现奇数 然后出现偶数 我尝试过但没有成功 我是java编码新手 我想测试递归 public class Recu
  • 导致 ValueError: 'b' in __slots__ 与类变量冲突的数据类和槽

    我不明白错误消息 也找不到其他问题和答案来帮助我理解这一点 MWE 使用 Python 3 9 2 进行测试 我知道有一个slots TruePython 3 10 数据类中的参数 但这不是这里的选择 错误输出 Traceback most
  • 如何查看Vite项目中的公共目录进行热加载?

    我有一个使用 Vite 配置的 React 项目 热重载效果很好 但我使用react i18next对于多语言支持 这是我的结构 public gt en gt translation json gt ru gt translation j
  • 如何确定一系列循环数据中的高值和低值?

    我有一些代表周期性运动的数据 所以 它从高点到低点 然后又回来 如果你要绘制它 它就像一个正弦波 然而 每个周期的幅度略有不同 我想列出整个序列中的每个最大值和最小值 如果有 10 个完整的周期 我最终会得到 20 个数字 其中 10 个为
  • Worldwind - 形状总是显示在图像之上?

    我在 WorldWindowGLJPanel 的图层列表中添加了两个图层 其中之一是包含形状的 RenderableLayer 另一个是包含光栅图像的 BasicTiledImageLayer 一层包含一个对象 问题是 当我使用图层管理器
  • 抑制 C# 垃圾回收

    我的应用程序分配大量内存 数百万个小对象 总计几千兆字节 并保留很长时间 NET 是否浪费时间检查所有这些数据来对其进行 GC 第 2 代 GC 检查所有对象的 GC 多久发生一次 有什么办法可以降低它的发生频率或者暂时抑制它的发生吗 我确
  • 如何在 Elasticsearch 中同时按父字段和嵌套字段排序?

    我需要同时按父字段和嵌套字段在 Elasticsearch 中排序 我的数据是这样的 id 1 rank 8 price 12 45 offers id 777 rank 12 price 45 75 id 2 rank 35 price
  • 自定义弹出菜单背景不适用于 Theme.AppCompat.Light.DarkActionBar android

    我做了一个popup menu 现在我想自定义它的背景颜色 我已经遵循了一些教程和 stackoverflow 但没有任何效果 应用程序基本主题是 Theme AppCompat Light DarkActionBar my style c
  • 如何对 HashSet 进行排序?

    对于列表 我们使用Collections sort List 方法 如果我们想对一个排序怎么办HashSet HashSet 不保证其元素的任何顺序 如果您需要这种保证 请考虑使用 TreeSet 来保存您的元素 但是 如果您只需要针对这一
  • sed:同时就地替换并打印更改行?

    假设我有这个文件 cat gt test txt lt
  • 直接从数据库返回 IEnumerable 或之前使用 ToListAsync

    当直接从数据库提供 IEnumerable 时 控制器如何工作 哪个代码更正确 更优化 假设数据库非常慢并且正在进行其他操作 这个示例非常简单 因此执行时间可能没有足够的差异 但我正在尝试学习最佳实践 1 public Task