7

我们目前正在调查在我们的Web API中使用OData查询语法。 我们不打算实现完整的OData实现 - 仅仅利用查询语法。ASP.NET Web API OData - 将DTO查询转换为实体查询

它通常被认为是很好的应用程序体系结构,可将您的应用程序分为几个层。 在现代Web应用程序中,这些图层将包含一个数据层和UI /传输层,可以将数据库中存储的信息发送给客户时对其进行不同的建模。

例如:你可以有一个数据库(实体框架)的模型,看起来像这样:

public class Employee 
{ 
    public Guid Id {get; set;} 
    public string Name {get; set;} 
    public int AccessLevel {get; set;} 
} 

但你的Web的API可能在不同的传输格式将这些资料给你的客户:

public class EmployeeDto 
{ 
    public string Name {get; set;} 
    public string SecurityClearence {get; set;} 
} 

使用ASP.NET Web API和(大概??)Microsoft ASP.NET Web API OData库我们将如何实现这样的场景,即我们的客户将针对DTO格式编写查询 例如:

?$filter=(SecurityClearence eq 'TopSecret') 

...然后我们会根据我们的数据格式来翻译它。 如:

?filter=(AccessLevel eq 007) 

或其他格式,让我来动态查询我的数据库,如表达。 如:

db.Employees.Where(translatedExpression); 

我已经想到了几种方法来实现手动这一点,但我渴望知道别人会怎么解决这个问题,因为我觉得我的实现至今是相当粗糙的,不可能容纳审查。

Web API OData库(以及相关的EDM库)的功能是否可以为我实现部分或全部功能?

回答

0

我们一直在使用Entity Framework,Automapper和LinqToQueryable的组合。

一个典型的控制器动作应该是这样的:

[HttpGet] 
[LinqToQueryable] 
public IEnumerable<SomeViewModel> SomeAction() 
{ 
    return _databaseContext.Entities 
          .Where(e => e.SomeProp = "Example") 
          .Project() 
          .To<SomeViewModel>(); 
} 

我们所需要的的NuGet包名,LinqToQuerystringlinqtoquerystring.entityframeworkLinqToQuerystring.WebApi。该文档在这里:http://linqtoquerystring.net/

+0

我会看看那个软件包,我看着写一些类似的东西。 我不喜欢我提出的两个原因:1)预测是在SQL中完成的,这意味着我们不再查询关键指标。 2)我们对我们的API进行了版本管理,并且我不想为每个API版本编写不同的投影。我首选的方法是在查询数据库之前翻译它们的查询。虽然这感觉更难。 –

2

加文,

我知道我可能是太晚了这个派对,但这里是我的两分钱在这个问题上。

早在2013年,我在一个项目中工作,想出了这个相同的场景。我有一个实体模型,还有一个DTO模型可以传入和传出服务层。我做了我的研究,但没有找到任何允许我使用的库:1.以自动方式从我的实体模型映射到我的DTO模型,以及2.将DTO上的表达式转换为实体模型的过滤和排序。

最后我决定编写我自己的“预测”框架。几个月前,我发布了代码GitHub,并上传了一个NuGet包,以防有人需要这样做。

现在,如果您决定试用它,您必须构建并配置ProjectionsModel(类似于您将如何配置EF代码优先数据模型)并指定DTO模型类如何映射到实体模型类。

然后,您可以创建一个模型,并用它来预测和DTO查询渗入到实体的查询:

IQueryable<UserAccountEntity> usersQuery = usersList.AsQueryable(); 

var myProjectionModel = new MyProjectionModel(); 
var dtoUsersList = myProjectionModel.Project<UserAccountDTO, UserAccountEntity>(usersQuery).ToList(); 

即使强硬过滤不是一部分。例如,您可以创建的集合QueryFilterQuerySorter对象,并将它们作为参数发送到Project方法。

让我知道如果你想知道更多关于这个图书馆。

+0

你完成的这项工作真的很棒。非常感谢。 – user326608