1

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

这是我的模型:

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>
}
4

3 回答 3

1

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

于 2012-12-28T14:54:30.373 回答
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 的要点之一,即将业务逻辑与视图分离。

看起来您的永久解决方案应该是将距离存储在数据库中。当您向加油表添加新记录时,您应该首先获取前一条记录并计算添加新记录时要包含的距离。您所添加的只是一个额外的调用来获取单个记录,并且数据库操作足够便宜,您应该只看到非常大规模的差异。但即便如此,以上所有这些工作无论如何都将在服务器上完成,并且每次重复它的成本可能要高得多。

于 2012-12-28T14:46:26.387 回答
0

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

于 2012-12-28T15:12:47.910 回答