我正在学习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。这让我感到困惑,因为同一个模型得到了两个结果。
那么两种方法之间有什么区别,什么是更好的选择?
谢谢所有程序员!
答案 0 :(得分:5)
使用@Model.NavigationProperty.SubProperty
要求Model
和NavigationProperty
都不是null
。它与访问方法中的SubProperty
属性没有什么不同。
然而,使用Html.DisplayFor()
使用模型元数据生成html,Model
和NavigationProperty
都可以是null
,因为该方法不会直接访问该属性。
DisplayFor()
的一个主要用途是使用应用于该属性的任何[DisplayFormat]
属性。例如,如果属性的值使用null
属性为NullDisplayText
,则可以指定要呈现的文本,或者使用{{以特定格式呈现DateTime
或数字属性1}}属性。
在您的情况下,查询应该是
DataFormatString