视图中的空导航属性

Jun*_*ang -1 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; }
    }
Run Code Online (Sandbox Code Playgroud)

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

        public ICollection<Bag> Bags { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

当我创建一个新的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);
    }
Run Code Online (Sandbox Code Playgroud)

基本上,我绑定了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());
Run Code Online (Sandbox Code Playgroud)

和观点:

<h4>@bag.BagName - @bag.Category.CategoryName</h4>
Run Code Online (Sandbox Code Playgroud)

但这给了我带<h4>标签的行的NullReference异常.删除AsNoTracking()不会改变任何东西.

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

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

谢谢所有程序员!

小智 5

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

使用Html.DisplayFor()但使用模型元数据来生成HTML和双方ModelNavigationProperty可以null,因为该方法不直接访问属性.

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

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

var Bags = db.Bags.Include(b => b.Category).Include(b => b.Supplier);
return View(await Bags.ToListAsync());
Run Code Online (Sandbox Code Playgroud)