c# - ASP.NET MVC Razor View 建立在两个对象的 Viewmodel 之上。架构建议如何更新引用两个对象的计算字段

标签 c# asp.net asp.net-mvc asp.net-mvc-4 razor

我在 ASP.NET MVC5 项目中工作,有一个名为 PlacementStudentIndexData 的 View 模型类,它有四个 Ienumerables 集合,

View 模型类声明如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Placementv2.Models;
using IdentitySample.Models;
namespace Placementv2.ViewModels
{
    public class PlacementStudentIndexData
    {
        public IEnumerable<ApplicationUser> UserChoice1 { get; set; }
        public IEnumerable<ApplicationUser> UserChoice2 { get; set; }
        public IEnumerable<ApplicationUser> UserChoice3 { get; set; }
        public IEnumerable<Placement> Placement { get; set; }
        public double distance { get; set; }
    }

请注意,ApplicationUser 使用的是 Identity2.0 中对象上的用户对象。

Placements Controller 有一个 Details Action,用于将 ViewModel 数据传递到基于此 ViewModel 构建的 razor View ,该 ViewModel 执行两个对象之间的匹配练习,并返回三个匹配的 Users 集合和一个具有单个 Placement 类型实例的集合传递给 Action 以指示返回哪个 Placement 对象的 int 值)

  public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var viewModel = new PlacementStudentIndexData();
        viewModel.Placement = db.Placements.Where(p => p.PlacementID== id.Value);
        viewModel.UserChoice1 = db.Users.Where(p => p.Choice1 == viewModel.Placement.FirstOrDefault().PlacementOrganisation.PlacementTypeID).Where(p => p.Placed == false);
        viewModel.UserChoice2 = db.Users.Where(p => p.Choice2 == viewModel.Placement.FirstOrDefault().PlacementOrganisation.PlacementTypeID).Where(p => p.Placed == false);
        viewModel.UserChoice3 = db.Users.Where(p => p.Choice3 == viewModel.Placement.FirstOrDefault().PlacementOrganisation.PlacementTypeID).Where(p => p.Placed == false);


        return View(viewModel);

在我的 Placement Controller 的其他地方,我有以下方法,并且正在寻找有关如何将此距离更新为针对当前放置实例计算的单个用户实例的建议。计算应基于传递的地理坐标,这些地理坐标已存储在用户对象和 PlacementOrganisation(与 Placement 相关联)的数据库中

 public double CalculateDistance(double startlat, double startlong, double endlat, double endlong)
            {
[Google MAPS API calculation and JSON deserialisation code here]
                return distancekms;    
            }

我的困难是在我的代码中执行这些计算的位置,我正在寻找有关如何更新现有三个 UserChoice1、UserChoice2、UserChoice3 集合的距离属性的建议(作为旁注,我知道这些是 ienumerables,将它们描述为集合是错误的吗?)

如果可以,有人可以给我一个示例,说明我如何扩展我的 Details Controller 操作以包括对此 CalculateDistance 方法的调用,以便每个 User 实例的更新距离属性是传递给 Razor View 的 ViewModel 的一部分。

注意 - 我已经尝试在 Controller 方法中包含一个 foreach block ,它按照以下几行调用 CalculateDistance 方法

foreach (var item in viewModel.UserChoice1)
            {
                viewModel.UserChoice1.First().distance = Calculatedistance(viewModel.Placement.First().PlacementOrganisation.Latitude, viewModel.Placement.First().PlacementOrganisation.Longtitude, viewModel.UserChoice1.First().Latitude, viewModel.UserChoice1.First().Longtitude);
            }

但是,它抛出以下异常: “已经有一个与此命令关联的打开的 DataReader,必须先将其关闭。”

如果您能在我的 Placement Controller 的 Details 操作中看到实现我在这里尝试做的事情的方法,请告诉我。或者,我应该在遍历 User 对象时从 View 中调用此 CalculateDistance 方法,还是在 View 本身中通过 Javascript 执行计算。

在此先感谢您提供的任何帮助/建议。

最佳答案

@Dandy 提供的链接确实包含该链接上投票较低的答案之一的解决方案。

解决方案是将 .ToList() 附加到 Ienumerables,这似乎可以正确关闭 DataReader。

这最终让我解决了 foreach 循环抛出错误的问题

public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var viewModel = new PlacementStudentIndexData();
            viewModel.Placement = db.Placements.Where(p => p.PlacementID == id.Value).ToList();
            viewModel.User = db.Users.Where(p => p.Placed == false).OrderBy(p=>p.distance).ToList();


            foreach (ApplicationUser user in viewModel.User)
            {
               user.distance = Calculatedistance(user.Latitude,user.Longtitude, viewModel.Placement.FirstOrDefault().PlacementOrganisation.Latitude, viewModel.Placement.FirstOrDefault().PlacementOrganisation.Longtitude);

            }
              return View(viewModel);

        }

关于c# - ASP.NET MVC Razor View 建立在两个对象的 Viewmodel 之上。架构建议如何更新引用两个对象的计算字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32549596/

相关文章:

javascript - ASP.NET:将数据从客户端发送到服务器

c# - C# 向数据库中输入数据

asp.net - 处理 ASP.NET MVC Controller 构造函数中发生的异常

c# - 从 XAML 设置 ViewModel 的属性

asp.net-mvc - @helper 和 Url.Action

asp.net-mvc - 实现自定义 MVC 基本 View 页面

asp.net-mvc - asp.net mvc 中的节脚本与脚本标记

c# - 在 c# 中为 Vector256 准备数据的最快方法是什么?

c# - 不可变对象(immutable对象)总是线程安全的吗?

C# 委托(delegate)事件处理程序 SelectedIndexChanged