WebAPI 中的 DTO 和投影

2024-01-31

WebAPI支持OData,因此API使用者可以指定他需要的字段,而且效果很好。但是有没有办法在 WebAPI 中使用 DTO 对象和投影呢?

例如我有

public class WebSite
{
    public string Url {get;set;}
    public string Author {get;set;}
    public string Technology {get;set;}
    public DateTime CreatedAt {get;set;}
    // 20 more different properties
}

我还有 DTO 对象:

public class WebSiteDTO
{
    public string Url {get;set;}
    public string Author {get;set;}

    public bool IsDotNet {get;set;} // it should be set during mapping as webSite.Technology == ".Net";
    public bool IsTrendThing {get;set;} // should be set as  webSite.Technology == ".Net" and webSite.CreatedAt > new DateTime(2014,0,0);
}

以及一些支持 OData 的典型 WebAPI 端点:

[HttpGet]
[Route("Test")]
public IQueryable Test(ODataQueryOptions<WebSiteDTO> options)
{
    var efDbContext = new MyDBContext();
    var query = efDbContext.WebSites;
    var odataQuery = options.ApplyTo(query, settings);
    return odataQuery;
}

在这种情况下,将返回 WebSite 对象。但是如何返回 WebSiteDTO 对象并仍然具有 OData 支持?是否可以按属性而不是按类本身进行映射?就像如果通过 OData 请求 Url,那么我们将从 DB 加载 Url 并将其映射到 DTO 对象中的 Url 属性?当 DTO 中的属性必须由某种自定义逻辑(如 IsDotNet 示例中)设置时,我可能会遇到复杂的情况,或者它可能依赖于多个属性。

我想我可以编写一些自定义中间件,它将使用 OData 指定的字段执行原始查询,然后将其保存在 Dictionary 中,然后执行类似的操作:

MyMapper.Map<WebSite, WebSiteDTO>().
    MapProperty(o, dict => o.Url = (string)dict["Url"]).
    MapProperty(o, dict => o.IsDotNet = (string)dict["Technology"] == ".Net").
    MapProperty(o, dict => o.IsTrendThing = (string)dict["Technology"] == ".Net" && (DateTime)dict["CreatedAt"] > new DateTime(2014,0,0));

但它看起来很难看,在这种情况下,我需要指定如果在 OData 请求中请求 IsTrendThing 属性,那么我还需要从 WebSite 对象加载 Technology 和 CreatedAt 字段,这使事情变得复杂。

有什么对我的情况有用的吗?也许有人可以帮助我正确的方向?

自动映射器有投影映射 https://github.com/AutoMapper/AutoMapper/wiki/Projection但它在我的场景中不起作用,因为它需要特定类型,并且在我的情况下,由于 OData 指定的字段,原始类型可能会有所不同。

另一个类似的问题 https://stackoverflow.com/questions/16962081/asp-net-webapi-odata-support-for-dtos但这是关于纯粹的 DTO,在我的例子中,我想支持 OData 中的“select\expand”运算符,因为我的对象可以有很多属性。如果没有请求,我不想从数据库加载它们。


您应该在应用 ODataQueryOptions 之前进行投影。 ODataQueryOptions 可应用于 WebSiteDto 中存在的属性。

var date = new DateTime(2014,0,0);
// this will not load your data
var query = efDbContext.WebSites.Select(w => new WebSiteDto() 
{
    /* projection code */
    IsDotNet = w.Technology == ".Net",
    IsTrendThing = w.Technology == ".Net" && w.CreatedAt > date,
    Url = w.Url,
    Author = w.Author
});

// this will still not load your data but will be applied on your projected object
var odataQuery = options.ApplyTo(query, settings);

仅当控制器操作返回时才会执行完整查询(应用了选项)。您可以在 select 方法中执行任何与 LinqToEntities 配合使用的投影代码(避免调用 Equals 等方法,而使用 == 代替或调用任何构造函数)。您甚至不加载 Technology 或 CreatedAt,查询在 SQL Server 上执行,并且仅返回布尔值。

如果客户端将执行额外的 $select ,它将被放置在该查询之上,因此不必要的数据将永远不会从 SQL Server 到达您的应用程序服务器(就像在 IQueryable 上应用另一个 .Select() 一样)

我不确定 AutoMapper 如何处理 IQueryable(是否强制评估查询),但 Select 方法不会评估您的查询,只会在其基础上进行构建,以便将其发送到 SQL Server。

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

WebAPI 中的 DTO 和投影 的相关文章

  • 使用 EF6 连接到 SQL Server

    在 EF5 之前 为了连接到 SQL Server 2012 我所需要做的就是指定一个如下所示的连接字符串 Data Source SqlExpress Initial Catalog MyDatabase Integrated secur
  • 从 Orchard 内的主题渲染图像

    我刚刚选择 Orchard 来构建我的博客 作为创建这个新博客的努力的一部分 我正在创建一个自定义主题 这个自定义主题同时具有 CSS 和图像 我的问题 我的问题基本上可以归结为 如何渲染属于主题一部分的图像 到目前为止我已经尝试过的 我尝
  • HTML 属性 bgcolor 已弃用:用什么代替?

    VStudio ASP NET 给出以下消息 Attribute bgcolor is considered outdated A newer construct is recommended 推荐的结构是什么 bgcolor是在一个 td
  • 简单的 Linq 查询对同一个表有重复的连接?

    来自 Julia Lerman 的新实体框架书中的示例 我有一个包含两个表的数据库 联系人和地址 Contact 表有一个 ContactID int 以及名字 姓氏等 Address 表有一个 ContactID 以及城市 州 邮政编码等
  • 正则表达式最多匹配五个单词

    我有一个正则表达式 a zA Z 0 9 1 5 它验证该单词包含字母数字字符和少数特殊字符 并且长度不应超过5人物 如何使此正则表达式接受最多五个与上述正则表达式匹配的单词 a zA Z 0 9 1 5 s a zA Z 0 9 1 5
  • 将 F# 类型保存到数据库

    A lot http gorodinski com blog 2013 02 17 domain driven design with fsharp and eventstore f 文章数推荐 http fsharpforfunandpr
  • MVC 操作过滤器和多线程

    我目前遇到了操作过滤器的线程问题 在我的应用程序上 我使用 ActionFilter 来执行每个操作的跟踪 此跟踪将提供统计信息 例如调用的持续时间 并记录参数被派往行动 实际的跟踪实现 由其他团队完成 使用 IDisposable 对象
  • 获取GridView中选定行的索引

    我想使用复选框获取从 gridview 选择的行 复选框是这样的
  • 将 Windows 窗体应用程序转换为 Asp.net

    我问的是 您之前使用的将 C Windows 窗体应用程序转换为 ASP NET 的最佳工具是什么 我已经关于这个主题 发现了很多工具 但我希望有人根据他的使用情况推荐最好的工具 我真的不建议使用工具来进行转换 Web 应用程序和 WinF
  • oracle ExecuteNonQuery 在 ASP.Net 上冻结

    我正在尝试使用 ASP C 和 CLR 4 5 中的 Oracle 连接来运行非查询 这是我的代码 string connectionString ConfigurationManager ConnectionStrings OracleC
  • 如何在asp.net中的按钮单击事件调用之前和之后调用javascript函数

    我在 ASP NET 中创建了 ButtonClick 函数 如下所示
  • Azure 云服务在应用程序池回收后停止运行

    我部署了一个 Azure 云服务 WebRole WebAPI 只有一个实例 我注意到 如果我等待一些空闲时间 没有 HTTP 请求 那么稍后服务就会死掉 并且对它的每个请求都会导致以下响应 Message An error has occ
  • 在c#中映射两个类

    我有两节课 public class foo1 public int id public string image link public string sale price and public class foo2 public int
  • 处理与不同相关实体的一对多的正确模式

    我有一个 C 项目 我使用实体框架作为 ORM 我有一个User 可以向多家银行付款 每家银行都是一个独立的实体 并且每家银行都由不同的字段描述 问题是 一User可以没有或有很多不同的Banks 我不太确定如何对此进行建模 临时解决方案是
  • 为什么 EF Core 使用此存储过程总是返回 -1?

    我正在尝试对本地 2016 DB 使用 EF Core 最新版本 并且我得到 1每次都回来 我不知道我做错了什么 我知道它正在到达数据库 我查了一下 int returnCode dbContext Database ExecuteSqlC
  • 为什么同时存在 System.Net.Http 和 System.Web.Http 命名空间?

    这只是一个简单的问题 因为我正在研究 NET 中可用的各种类库 我注意到有一个System Net Http命名空间和一个System Web Http命名空间 这两个命名空间都有什么用途 创建两个看似不明确的命名空间的动机是什么 是否有任
  • 使用实体框架从 2 个表返回数据

    我正在使用 MVC3 和实体框架 但我需要来自不同表的更多数据 通常我会做这样的事情来从表中获取数据 Table Users id username 在代码中我会做这样的事情来获取所有用户 public static IEnumerable
  • 从类型获取 DbSet

    我正在尝试为 MVC 6 应用程序制作通用表查看器 编辑器 我目前使用 Context GetEntityTypes 返回给我一份表格列表 现在我需要获取特定类型的数据 我当前的实现是 On my context public IQuery
  • SQL服务器超时

    我的应用程序是在经典 asp 上开发的 但也使用 asp net 因为我正在将应用程序迁移到 Net 上 它使用 SQL Server 作为数据库并托管在 Windows Server 2003 上 现在的问题是应用程序在很长一段时间内继续
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体

随机推荐

  • 如何将犰狳与 Eclipse 链接

    我想将犰狳与 Eclipse 一起使用 然而 链接犰狳的所有说明都是针对 Visual Studio 给出的 现在我按照自述文件中概述的说明进行操作犰狳图书馆 http arma sourceforge net download html
  • DBus如何启动服务

    我很好奇如何为 DBus 启动自己的服务 在官方网站上 我找到了很多有关从客户端角度使用 DBus 服务的信息 但如何启动和开发服务还不够 1 接口文件ServiceName xml应该位于哪里 2 服务文件ServiceName serv
  • Firefox 扩展:取消请求并发出虚假响应

    我正在尝试开发一个 Firefox 扩展 它可以丢弃对某个站点的每个 HTTP 请求并返回一个虚假响应 任何请求都不应到达原始 Web 服务器 但我希望能够创建自定义响应 我尝试拦截 http on modify request 消息 但取
  • 基于Web服务实现快速更新行标签

    我有一个包含 7 行的表视图 周一 周二 周日 我的应用程序从 Web 服务接收一个 json 其格式为 appointments numApts 1 scheduleDate 2015 11 02 numApts 2 scheduleDa
  • C# 将 int 转换为字符串并填充零?

    在 C 中 我有一个整数值需要转换为字符串 但需要在之前添加零 例如 int i 1 当我将它转换为字符串时 它需要变成 0001 我需要了解 C 中的语法 i ToString PadLeft 4 0 好的 但不适用于负数 i ToStr
  • 如何更改 UISearchBar 字体大小和颜色?

    我已经用谷歌搜索了几个小时如何更改我的 UISearchBar 字体大小和颜色 但我无法找到任何与之相关的文档 这是我到目前为止在 swift 4 上所做的 searchBar UISearchBar frame CGRect x 0 y
  • 为什么可以在同一个类中创建的另一个线程中访问局部变量?

    我真的找不到关于这个确切主题的任何内容 所以如果问题已经存在 请引导我走向正确的方向 根据我对 NET 的了解 不可能跨不同线程访问变量 如果该语句错误 请纠正我 这只是我在某处读到的内容 然而 现在在这个代码示例中 它似乎不应该工作 cl
  • 将背景颜色设置为 HighChart xAxis 标签

    如何为 HighChart xAxis 标签设置背景颜色 我尝试了以下但没有运气 x轴 类别 一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月 标签 旋转 90 风格 颜色 89A54E 填写 000 背景颜色 F
  • 导航到“url”,等待“load” - Python Playwright Issue

    嘿 我在 python playwright 中有用于获取页面源代码的代码 import json import sys import bs4 import urllib parse from bs4 import BeautifulSou
  • 悬停后保持下拉菜单打开(CSS)

    我创建了一个水平菜单 当您将鼠标悬停在某个项目上时 会出现一个下拉菜单 这一切都很好 但是 当您离开菜单项 使用下拉菜单 时 下拉菜单就会消失 我知道这是因为你不再悬停它 但我该如何解决这个问题 注意 我不希望下拉菜单直接位于其下方 我希望
  • 无法在 Angularjs 中使用 templateUrl 加载模板

    我刚刚学习 Angularjs 以及如何使用 templateUrl 加载模板 我有一个简单的指令 var mainApp angular module mainApp mainApp directive request function
  • 如何将文本区域的标签对齐到顶部?

    我确实有一个表格数据 如下所示 td td
  • 空字符串而不是不匹配的组错误

    我有这段代码 for n in range 1 10 new re sub r regex group regex regex r something str n r 1 old count 1 它会抛出不匹配的组错误 但如果它不匹配 我想
  • 启用 Vuforia 时 Unity 崩溃

    在 XR 设置中启用 Vuforia 增强现实支持 时 我的编辑器崩溃 以下是我遵循的步骤 重现步骤 1 创建一个新项目 2 文件 gt 构建设置 gt 播放器设置 gt 播放器 3 从 XR 设置中启用 Vuforia 增强现实 复选框
  • 使用 matplotlib 从图中获取数据

    我在 python 中使用 matplotlib 来构建散点图 假设我有以下 2 个数据列表 X 1 2 3 4 5 Y 6 7 8 9 10 然后我使用X作为X轴值 Y作为Y轴值来绘制散点图 所以我会有一张上面有 5 个散射点的图片 对吧
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • 通过网络桥接串行端口

    对于使用串行端口进行通信 确切地说是 Modbus RTU 的应用程序 我需要通过网络桥接串行端口以进行测试 所以我想要以下设置 Device Network PC SerialPort SerialPort Map Serialport
  • 如何将节点标题放置在 d3 Sankey 图中节点的左侧或右侧?

    这是我指的例子 http bl ocks org d3noob c9b90689c1438f57d649 http bl ocks org d3noob c9b90689c1438f57d649 第二级节点的标题位于其右侧 如何将它们放置在
  • 函数导入(存储过程)需要 SaveChanges() 吗?

    Is 保存更改 函数导入 存储过程 有必要吗 Example void foo Product product AddProduct is a function import of a stored procedure entities A
  • WebAPI 中的 DTO 和投影

    WebAPI支持OData 因此API使用者可以指定他需要的字段 而且效果很好 但是有没有办法在 WebAPI 中使用 DTO 对象和投影呢 例如我有 public class WebSite public string Url get s