计算连续记录中的距离

时间:2012-12-28 14:15:57

标签: c# asp.net-mvc-3 visual-studio-2010

我正在开发一个跟踪加油的应用程序。 每条记录都存储有关加油站访问的数据。 我决定尽可能少地在数据库中存储信息,并在控制器中计算内容。

这是我的模特:

public class Refuel
{
    #region Properties

        public int id { get; set; }
        public int mileage { get; set; }
        public DateTime date { get; set; }
        public Nullable<double> volume { get; set; }
        public Nullable<double> price { get; set; }

        public Nullable<int> imageId { get; set; }
        public Nullable<int> gasstationId { get; set; }

        public virtual Gasstation Gasstation { get; set; }
        public virtual Image Image { get; set; }

    #endregion

    #region Methods

        public int distance { get; set; }

        [DisplayFormat(DataFormatString = "€ {0:0.00}")]
        public Nullable<double> totalPrice
        {
            get
            {
                return volume * price;
            }
        }

        [DisplayFormat(DataFormatString = "{0:0.00}")]
        public Nullable<double> consumption
        {
            get
            {
                if (distance > 0)
                    return volume / distance * 100;
                else
                    return 0;
            }
        }

        [DisplayFormat(DataFormatString = "{0:0}")]
        public Nullable<double> consumption2
        {
            get
            {
                if (distance > 0)
                    return distance / volume;
                else
                    return 0;
            }
        }

        [DisplayFormat(DataFormatString = "{0:0.00}")]
        public Nullable<double> mileageLeft
        {
            get 
            {
                return volumeLeft * consumption2;
            }
        }

        [DisplayFormat(DataFormatString = "{0:0.00}")]
        public Nullable<double> volumeLeft
        {
            get
            {
                double? d = 45 - volume;
                return d;
            }
        }

    #endregion
}

正如你所看到的,我对这里的距离做了什么。 我在一个特定记录的详细信息页面中计算距离。

我现在要做的是在索引页面上总结一下距离并计算平均消耗量。 这都是相对于距离的,但此时这是一个空场。

我在索引页面上显示所有记录的列表时遇到了同样的问题。 距离和消耗列为空。

在那一点上填充距离的最佳方法是什么? 或者最好将距离存储在数据库中?

这是我的索引功能:

    [HttpGet]
    [Authorize]
    public ActionResult Index(string sortOrder, int? page)
    {
        ViewBag.CurrentSort = sortOrder;
        ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "asc" : "";

        List<Refuel> rf = db.Refuels.ToList();
        var refuels = from t in db.Refuels select t;

        switch (sortOrder)
        {
            case "asc":
                refuels = refuels.OrderBy(q => q.mileage);
                break;
            default:
                refuels = refuels.OrderByDescending(q => q.mileage);
                break;
        }

        // statistieken
        ViewBag.count = rf.Count();
        ViewBag.distance = rf.Sum(q => q.distance);
        ViewBag.volume = rf.Sum(q => q.volume);
        ViewBag.consumption = String.Format("{0:0.0}", rf.Where(q => q.consumption > 0).Average(q => q.consumption));
        ViewBag.consumption2 = String.Format("{0:0.0}", rf.Where(q => q.consumption2 > 0).Average(q => q.consumption2));
        ViewBag.cost = String.Format("{0:c2}", rf.Sum(q => q.totalPrice));

        int pageSize = 10;
        int pageNumber = (page ?? 1);
        return View(refuels.ToPagedList(pageNumber, pageSize));
    }

修改 管理修复摘要部分,当然我可以使用最后和第一个里程来获得总距离驱动:

ViewBag.count = tb.Count();
ViewBag.distance = tb.Last().mileage - tb.First().mileage;
ViewBag.volume = tb.Sum(q => q.volume);
ViewBag.consumption = String.Format("{0:0.0}", ViewBag.volume / ViewBag.distance * 100);
ViewBag.consumption2 = String.Format("{0:0.0}", ViewBag.distance / ViewBag.volume);
ViewBag.cost = String.Format("{0:c2}", tb.Sum(q => q.totalPrice));

我现在需要做的就是在索引表中显示每条记录的距离。 这是我的index.cshtml中的循环:

@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.ActionLink(Html.DisplayFor(modelItem => item.mileage).ToString(), "Details", new { id = item.id })
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.date)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.distance)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.volume)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.consumption)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.totalPrice)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Gasstation.fullname)
        </td>
    </tr>
}

3 个答案:

答案 0 :(得分:1)

无论你在单个记录的详细页面中做什么来计算距离都必须在这种情况下完成。如果您认为该操作比在数据库中存储距离字段更昂贵 - 您就得到了答案。

答案 1 :(得分:0)

您可以在视图中自行计算。只需在集合上运行for循环以显示您的记录,并将最后的加油里程作为i + 1或i-1(基于ViewBag.CurrentSort)并在那里进行数学运算。

修改 没有测试过这个,但这就是它的样子:

您必须返回一条额外的记录来计算集合中第一条或最后一条记录的距离,因此您必须更改ToPagedList方法以接受排序顺序,并在您想要的记录之前或之后返回额外的项目显示。

然后你的for循环看起来像:

@{
    bool asc = ((string)ViewBag.CurrentSort).ToLower() == "asc";
    int i = 0;
    int records = Model.Count;

    //If sort is asc you want to skip the first record (the extra record you returned to do the calculation), else you want to stop before you get to the extra row at the end of the collection
    if (asc) i += 1;
    else records -= 1;

for (i; i<records; i++)
{
<tr>
    <td>
        @Html.ActionLink(Model[i].mileage.ToString(), "Details", new { id = Model[i].id })
    </td>
    <td>
        @Html.DisplayFor(modelItem => Model[i].date)
    </td>
    <td>
        @if (asc) {
        @Html.Display(Model[i].mileage - Model[i - 1].mileage)
        }
        else {
           @Html.Display(Model[i].mileage - Model[i + 1].mileage)
        }
etc...

话虽这么说,但这应该是一项非常基本的功能。而且你开始摆脱MVC的一个要点,即将业务逻辑与你的观点分开。

看起来您的永久解决方案应该是将距离存储在数据库中。当您将新记录添加到加油表时,您应首先获得前一个记录并计算添加新记录时要包括的距离。所有你要添加的是一个额外的调用,以获得单个记录和数据库操作足够便宜,你应该只看到一个非常大的差异。但即便如此,上述所有这些工作仍将在服务器上进行,每次重复都可能会花费更多。

答案 2 :(得分:0)

您可以在模型中创建构造函数并将距离设置为0,然后担心以后填充它。