效率低下的MVC ViewModel对数据库进行多次调用?

时间:2013-06-26 11:37:09

标签: asp.net-mvc linq viewmodel

我显然不知道自己在做什么。这个MVC的东西真的在试图保持这种模式。我一直在关注MVC教程以及超级谷歌搜索,这是我自己画的角落。

我有多个类似的数据我正试图进入视图。我能够让我的代码工作,但对我而言,由于多次调用db,我们开始从db中提取大型记录集,因此它看起来效率非常低。所以,我有一个OrderSummary类,在类中是这样的:

public IEnumerable<Order> GetOrders()
{
   var orders = (from s in db.Orders
                 where s.UserId == uId
                 select s);

   return orders.ToList();
}

然后这个:

public decimal GetGrossProfitTotal()
{
   var orders = (from s in db.Orders
                 where s.UserId == uId
                 select s);
   decimal? grossprofittotal = orders.Sum(s => s.Profit);

   return grossprofittotal ?? decimal.Zero;
}

因此,如果我们采用最后一块代码并将其复制为totalcommission和netprofittotal,那基本上就是我的事情。我想猜四次调用db?

然后在控制器中:

        var ordersummary = new OrdersSummary();
        var viewModel = new OrderSummary
        {
            Orders = ordersummary.GetOrders(),
            GrossProfitTotal = ordersummary.GetGrossProfitTotal(),
            CommissionTotal = ordersummary.GetCommissionTotal(),
            NetProfitTotal = ordersummary.GetNetProfitTotal(),
        };
        return View(viewModel);

这会在视图中获取我需要的所有数据,以便我可以使用它。对我而言,这似乎是不必要的冗余,我猜测效率低下?如果你投入,我也在做排序和搜索parms,它也是很多重复的linq代码。看起来我应该能够做一些事情来巩固这样的数据:

   var orders = (from s in db.Orders
                 where s.UserId == uId
                 select s).ToList();

   decimal grossprofittotal = orders.Sum(s => s.Profit);
   decimal commissiontotal = orders.Sum(s => s.Commission);
   decimal netprofittotal = orders.Sum(s => s.Profit + s.Commission);

然后将这四个数据(订单列表和三个十进制值)很好地包装在一个数组(或其他)中,并将它们发送到控制器/视图。在视图中,我需要能够遍历订单列表。我离开这里了吗?或者,MVC的标准程序是什么?感谢。

2 个答案:

答案 0 :(得分:1)

是的,四次获取相同的数据确实效率低下,而且完全不必要。您只需获取一次,然后对您拥有的数据执行其他操作。

如果您愿意,可以保留GetOrders方法,但这是您需要获取的所有数据。如果您在控制器中获取数据或在模型构造函数中获取数据主要是品味问题。就个人而言,我倾向于在模型中放置比控制器更多的逻辑。

只要您使用ToList确保实际获取数据(或任何其他将结果实现为集合的方法),您就可以计算内存中的总和。 (没有它,你仍然会对数据库进行四次查询。)

您可以从其他总和中计算出来,而不是总结所有项目的利润和佣金以获得净利润总额:

decimal netprofittotal = grossprofittotal + netprofittotal;

答案 1 :(得分:1)

LinqToEntities将所有查询转换为SQL。如果您不想创建多个事务,可以通过.ToList()将结果提取到变量中,查询此对象可以通过内存中的linqToObject进行计算。

向后:它首先从数据库中获取所有订单。

 var ordersInMemory = orders.ToList();
 decimal grossprofittotal = ordersInMemory.Sum(s => s.Profit);
 decimal commissiontotal = ordersInMemory.Sum(s => s.Commission);
 decimal netprofittotal = grossprofittotal + commissiontotal ;