视图中的空导航属性

时间:2017-05-16 03:18:41

标签: c# asp.net-mvc razor asp.net-core

我正在学习ASP.NET核心MVC。我对使用@Model.NavigationProperty.SubProperty@Html.DisplayFor(modelItem=>modelItem.NavigationProperty.SubProperty访问导航属性之间的区别感到困惑。详情如下。

我有两个实体Bag和Category,它们是FK in Bag。

    public class Bag
    {
        public int BagID { get; set; }
        [Required,Display(Name ="Bag Name")]
        public string BagName { get; set; }
        [Required]
        [DisplayFormat(DataFormatString = "{0:C}")]
        public decimal Price { get; set; }
        public string Description { get; set; }
        [Display(Name ="Image")]
        public string ImagePath { get; set; }

        [Required]
        public int CategoryID { get; set; }
        [Required]
        public int SupplierID { get; set; }

        public ICollection<OrderItem> OrderItems { get; set; }
        public Category Category { get; set; }
        public Supplier Supplier { get; set; }
    }

    public class Category
    {
        public int CategoryID { get; set; }
        public string CategoryName { get; set; }

        public ICollection<Bag> Bags { get; set; }
    }

当我创建一个新的Bag时,我做了

public async Task<IActionResult> 
        Create([Bind("BagID,BagName,CategoryID,Description,Price,SupplierID")] Bag bag)
        {

        bag.Category = _context.Categories.Single(c => c.CategoryID == bag.CategoryID);
        bag.Supplier= _context.Suppliers.Single(s => s.SupplierID== bag.SupplierID);
        //....
      if (ModelState.IsValid)
      {
          _context.Add(bag);
          await _context.SaveChangesAsync();
          return RedirectToAction("Index");
      }
      //....  
        return View(bag);
    }

基本上,我绑定了CategoryID,并在创建时明确地将一个类别分配给了一个Bag。

显示行李和类别名称时,它涉及控制器中的索引操作,如下所示

var Bags = from bags in _context.Bags
          select bags;  //Retrieve all bags 

   Bags.Include(b => b.Category.CategoryName).Include(b=>b.Supplier.FullName); //Load navigation property

            return View(await Bags.AsNoTracking().ToListAsync());

和视图:

<h4>@bag.BagName - @bag.Category.CategoryName</h4>

但是这给了我<h4>标记行的NullReference异常。删除AsNoTracking()不会改变任何内容。

但是,当我在视图中更改为使用<h4>@bag.BagName - @Html.DisplayFor(b=>bag.Category.CategoryName)</h4>时,如果我使用AsNoTracking()并不重要,我没有例外,并且显示了CategoryName。这让我感到困惑,因为同一个模型得到了两个结果。

那么两种方法之间有什么区别,什么是更好的选择?

谢谢所有程序员!

1 个答案:

答案 0 :(得分:5)

使用@Model.NavigationProperty.SubProperty要求ModelNavigationProperty都不是null。它与访问方法中的SubProperty属性没有什么不同。

然而,使用Html.DisplayFor()使用模型元数据生成html,ModelNavigationProperty都可以是null,因为该方法不会直接访问该属性。

DisplayFor()的一个主要用途是使用应用于该属性的任何[DisplayFormat]属性。例如,如果属性的值使用null属性为NullDisplayText,则可以指定要呈现的文本,或者使用{{以特定格式呈现DateTime或数字属性1}}属性。

在您的情况下,查询应该是

DataFormatString