2017-05-16 70 views
-1

我正在學習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。這讓我感到困惑,因爲同一個模型有兩個結果。

那麼這兩種方法有什麼區別,什麼是更好的選擇?

謝謝大家!

回答

5

使用@Model.NavigationProperty.SubProperty要求ModelNavigationProperty都不是null。在方法中訪問SubProperty屬性沒有區別。

使用Html.DisplayFor()但使用模型元數據來生成HTML和兩個ModelNavigationProperty可以null,因爲該方法不直接訪問屬性。

DisplayFor()的主要用途之一是利用任何應用於屬性的[DisplayFormat]屬性。例如,如果使用NullDisplayText屬性的屬性值爲null,或者使用DataFormatString屬性呈現DateTime或特定格式的數字屬性,則可以指定要呈現的文本。

在你的情況下,查詢應該是

var Bags = db.Bags.Include(b => b.Category).Include(b => b.Supplier); 
return View(await Bags.ToListAsync()); 
+0

感謝斯蒂芬。你的回答很明白。但我仍然感到困惑,因爲當我使用'DisplayFor()'時,CategoryName可以被訪問和顯示,這意味着它不是空的,是嗎?那麼爲什麼我在使用'@ Model.NavigationProperty.SubProperty'時會得到Null引用異常? –