首页 > 解决方案 > C# - 从持久存储中检索数据并将其保存到视图模型

问题描述

你好我有一个控制器方法,我想返回看起来像这样的视图模型

如果它是硬编码的,这就是它的样子

 public ActionResult SpecialOrderSummary(int? id)
        {
            // Retrieve data from persistence storage and save it to the view model.
            // But here I am just faking it.
            var vm = new ItemViewModel
            {
                ItemId = 123,
                ItemName = "Fake Item",
                Parts = new List<ItemPartViewModel>
                {
                    new ItemPartViewModel
                    {
                        PartId = 1,
                        PartName = "Part 1"
                    },
                    new ItemPartViewModel
                    {
                        PartId = 2,
                        PartName = "Part 2"
                    }
                }
            };

            return View(vm);
        }

但我显然不希望它被硬编码。所以这就是我试图做的,而不是实现我的目标

  public ActionResult SpecialOrderSummary(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            JobOrder jobOrder = db.JobOrders.Find(id);
            if (jobOrder == null)
            {
                return HttpNotFound();
            }
            ViewBag.JobOrderID = jobOrder.ID;
            ItemInstance ii = db.ItemInstances.Where(x => x.serialNumber == jobOrder.serialNumber).FirstOrDefault();
            Item item = db.Items.Find(ii.ItemID);

            var vm = new ItemViewModel
            {
                ItemId = item.ItemID,
                ItemName = item.Name,
                Parts = new List<ItemPartViewModel>
                {
                  foreach(ItemHasParts ihp in item.IHP) 
                   {
                     Part part = db.Parts.Find(ihp.PartID);
                     new ItemPartViewModel
                     {
                        PartId = part.ID,
                        PartName = part.Name
                     };
                   }
                }
             };

            return View(vm);
        }

但这不起作用。因为它似乎无法识别} 打开的“Parts”和打开的“vm”括号的关闭,因为它跳过了两者。为什么是这样?

标签: c#asp.net-mvcmodelviewmodel

解决方案


嗯,我以为我之前回答过这个问题:https ://stackoverflow.com/a/62782124/2410655 。基本上你不能在视图模型中间有这样的 for 循环。

我想再添加两件事。

1.身份证?

如果特殊订单摘要需要一个 ID,请不要将其声明为可选。如果这样做,则必须添加更多逻辑来检查是否有 ID。

如果订单摘要需要一个 ID,只需将其声明为int id. 如果客户端不提供,让 MVC 框架处理错误。现在,根据您的设置,您的 MVC 可能会抛出 404、500 或用户友好的页面。由开发人员来设置它。

2.注意NullReference Exception

在您的代码示例中,我看到您FirstOrDefault()在 item 实例上使用过。如果它返回为 NULL 并且您调用db.Items.Find(ii.ItemID)...


因此,根据您的示例,我将代码更改为:

public ActionResult SpecialOrderSummary(int id)
{
    JObOrder jobOrder = db.JobOrders.Find(id);
    if (jobOrder == null)
    {
        return HttpNotFound();
    }

    ItemInstance itemInstance = db.ItemInstances
        .Where(x => x.serialNumber == jobOrder.serialNumber)
        .FirstOrDefault();

    Item item = null;
    if (itemInstance != null)
    {
        item = db.Items.Find(itemInstance.ItemID);
    }

    var vm = new JobOrderSummaryViewModel
    {
        JobOrderId = jobOrder.ID,
        Parts = new List<ItemPartViewModel>();
    };

    if (item != null)
    {
        vm.ItemId = item.ItemId;
        vm.ItemName = item.ItemName;

        foreach(ItemHasParts ihp in item.IHP) 
        {
            // Does Part and Item have many-to-many relationships?
            // If so, you might be able to get the part by
            // ihp.Part instead of looking it up using the ID.
            // Again, it depends on your setup.
            Part part = db.Parts.Find(ihp.PartID);

            if (part != null)
            {
                vm.Parts.Add(new ItemPartViewModel
                {
                    PartId = part.ID,
                    PartName = part.Name
                });
            }
        }
    }

    return View(vm);
}

笔记:

db.Parts.Find(ihp.PartID);您在循环 ( )内还有对数据库的额外调用。如果您有大量数据,这将导致性能问题。有什么方法可以让你一开始就获取你需要的所有数据吗?


推荐阅读