我正在學習ASP.NET Core MVC。我對使用@Model.NavigationProperty.SubProperty
和@Html.DisplayFor(modelItem=>modelItem.NavigationProperty.SubProperty
訪問導航屬性的區別感到困惑。詳情如下。視圖中的空導航屬性
我有兩個實體袋子和袋子裏的FK類別。
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; }
}
當我創建一個新書包,我沒有
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);
}
基本上,我綁定類別ID,並在創建時明確分配一個類別以袋。
當顯示包和類別名稱,它涉及到在控制器中的索引操作如下
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>
但是這給了我NullReference異常在與<h4>
行標籤。刪除AsNoTracking()
不會更改任何內容。
但是,當我在視圖中更改爲使用<h4>@bag.BagName - @Html.DisplayFor(b=>bag.Category.CategoryName)</h4>
時,如果使用AsNoTracking()
或不使用,我沒有出現異常並顯示CategoryName。這讓我感到困惑,因爲同一個模型有兩個結果。
那麼這兩種方法有什麼區別,什麼是更好的選擇?
謝謝大家!
感謝斯蒂芬。你的回答很明白。但我仍然感到困惑,因爲當我使用'DisplayFor()'時,CategoryName可以被訪問和顯示,這意味着它不是空的,是嗎?那麼爲什麼我在使用'@ Model.NavigationProperty.SubProperty'時會得到Null引用異常? –