【问题标题】:ASP.NET MVC API vs Web API Async [closed]ASP.NET MVC API 与 Web API 异步 [关闭]
【发布时间】:2015-01-03 02:07:18
【问题描述】:

我目前正在使用 ASP.NET MVC 和单个控制器来实现各种“API”。我正在使用从每个操作方法调用的服务/存储库模式。

类似于下面:

存储库:

    public IQueryable<Order> GetOrders()
    {
        return from sqlOrder in DB.Orders
               select new Order
               {
                   Id = sqlOrder.Id,
                   Name = sqlOrder.Name,
                   Price = sqlOrder.Price
               };
    }

服务:

    public List<Order> GetOrders()
    {
        return Repo.GetOrders().ToList();
    }

控制器/动作:

    public JsonResult GetOrders()
    {
        var orders = Service.GetOrders();

        return Json(orders, JsonRequestBehavior.AllowGet);
    }

一切都很好,但是我正在考虑转移到 WEB API 和 Async/Await

类似于下面:

存储库:(无变化)

    public IQueryable<Order> GetOrders()
    {
        return from sqlOrder in DB.Orders
               select new Venue
               {
                   Id = sqlOrder.Id,
                   Name = sqlOrder.Name,
                   Price = sqlOrder.Price
               };
    }

服务:

    public async Task<List<Order>> GetOrders()
    {
        return await Repo.GetOrders().ToListAsync();
    }

控制器/动作:

    [ResponseType(typeof(List<Order>))]
    public async Task<IHttpActionResult> GetOrders()
    {
        var orders = await Service.GetOrders();

        return Ok(orders);
    }

首先,这种 async/await 和 Repository 模式有什么问题吗?

将原始 MVC 框架用作端点的“API”有什么主要缺点吗?而不是使用“Web API”?

【问题讨论】:

  • 为什么投反对票.. 这不是意见我正在寻找关于为什么切换到异步/等待的事实
  • 不是 d/v'ter,但您的问题可以解释为“我为什么要搬家”。也许澄清/编辑最后几段以澄清这一点?
  • 应该没有任何缺点。功能本质上是一样的,WebAPI 只是提供了一种更加 RESTful-API 驱动的语义方式来实现功能。正如您所建议的,使用普通 MVC 可以实现相同的功能。
  • 是的。是否考虑过使用 - 啊 - 工作量更少但功能更多的东西?我的意思是,说真的,你遵循“确保我的 web api 尽可能地笨拙地使用,因为我需要数百次调用任何东西”的反模式。
  • @TomTom 除了没有 WebApi 之外,我不确定我是否听懂了你的意思。

标签: c# asp.net-mvc entity-framework asp.net-web-api async-await


【解决方案1】:

您几乎已经回答了自己的问题 :)

通过使用 async/await,iis 工作线程可以重用线程。假设您的 api 每秒接收 1000 个调用。如果您的线程限制设置为 100,则 900 个调用将等待空闲,直到请求完全完成。

但是,通过使用 async/await,线程将更快地分配给 900 个等待请求,并且负载将更快(并且更难)到达您的数据库。

假设您有一个最大线程数为 1、1 个持续 10 秒的 db 调用和一个可以在 50 毫秒内从 webrequest 启动 db 调用的服务器。
通过使用异步,您可以启动 200 个数据库调用(每 50 毫秒 1 个),而如果您不释放该线程,则为 1 个。

至于你的第二个问题:大多数人不会在他们的控制器内进行数据访问,但它是一个非常干净且易于理解的示例。
如果我的项目足够简单(想想网格屏幕),我什至更喜欢在控制器内部使用 EF 语句而不是创建 DAL 层。
不要忘记 EF 本身就是一个存储库,它甚至有一个内置的工作单元。 ..

编辑
将业务逻辑包装在与控制器分开的层中确实是一个好主意。
您可以使用服务并为每个要执行的查询公开一个方法,但我一直在走这条路,我通常发现我的服务变得相当臃肿,因为开发人员制作了越来越多他们认为合适的方法。

最近我采用了命令查询系统。查询只是返回数据,而命令只是做一些事情。这种分离有助于保持代码更简洁,并且开发人员在创建一个全新的 queryClass 时投入了更多的精力,就像他们在创建一个方法时所做的那样(即使影响是相同的)。

我通常会让我的查询有点动态,但不会太多。
例如,OrderQuery 可以包含 2 个构造函数,1 个带有 customerID,1 个带有 typeID)查询将根据其构造方式应用更多或更少过滤器。
如果我需要说出所有销售价值大于 X 的最新订单,我可能会创建一个新查询 GetOrdersByValue。
通过这种方式,查询本身可以保持简洁和集中(这会提高速度,并且开发人员不会重新启动轮子,因为他们认识到他们的请求应该已经存在)。

【讨论】:

  • 在我提交之后他改变了他的问题...... tssk。无论如何,将异步与存储库模式和 web.api 一起使用没有问题,web.api 会更迫使您使用 MVC 更开放的 REST(如果您想制作可靠的 API,这是一件坏事)。
  • 感谢您的回答 :) 所以我想使用服务/回购模式的原因是 2 倍。我可以将 EF 对象映射到 POCO,这很好。另外,假设我想通过以下方式获取订单:类型、对于每个客户等,我可以让服务方法清楚地代表每个调用。想法?
  • 只是在移动的过程中,我发现使用中介的命令查询比服务存储库干净得多
猜你喜欢
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 2015-02-03
  • 2014-03-15
相关资源
最近更新 更多