【发布时间】:2015-01-25 10:55:35
【问题描述】:
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 指定的字段执行原始查询,然后将其保存在字典中,然后执行类似的操作:
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 字段,这会使事情变得复杂。
有什么对我有用的吗?也许有人可以帮助我正确的方向?
Automapper has projections mapping 但它在我的场景中不起作用,因为它需要特定的类型,在我的情况下,由于 OData 指定的字段,原始类型可能不同。
有another similar question,但它是关于纯 DTO,在我的情况下,我想支持来自 OData 的 'select\expand' 运算符,因为我的对象可以有很多属性。如果没有请求,我不想从数据库加载它们。
【问题讨论】:
-
听起来像是 Automapper 的工作? automapper.org
-
谢谢大家,但是如果您查看我的问题的底部,我指出了 automapper 和第一个重复问题,那就是它们是不同的。我的问题是关于基于预测的 DTO。当 API 消费者可以指定 OData Select 表达式时,需要根据 Select OData 表达式将数据转换为 EF -> DTO -> 匿名类型。并且我不想加载整个 EF 对象并在 .Net 端进行转换,如果我可以将 DTO 的字段映射到 EF 实体和 SQL
标签: asp.net entity-framework asp.net-web-api odata projection