2017-05-05 81 views
1

我試圖學習ASP.Net Core,而且我很難弄清楚如何在MVC'樣式'(?)中移動數據。我所關注的微軟網站上的ASP.NET Core教程並不涉及模型之間的任何關係。 (對他們來說,似乎是一個愚蠢的疏忽?)也許我的Google-Fu關閉了,所以如果這是明顯的,或者任何人有一些閱讀材料,我可以看看ASPNETCore,我會很感激。理解如何在ASP.net中處理數據時遇到問題核心

我有兩個模型。一個叫設備,另一個叫做設備類型。 在我的設備模型中,我有一個對DeviceType屬性的引用。

public class Device{ 
    [Key] 
    public int ID {get; set;} 

    [Required] 
    [Display(Name = "Device Name")] 
    public String deviceName {get; set;} 

    [Required] 
    [Display(Name="Description")] 
    public String deviceDescription {get; set;} 

    [Required] 
    [Display(Name="Type")] 
    public DeviceType deviceType{get; set;} 
} 

public class DeviceType{ 
    [Key] 
    public int ID {get; set;} 
    [Required] 
    [Display(Name="Type")] 
    public String name {get;set;} 
    [Required] 
    [Display(Name="Description")] 
    public String description {get;set;} 

} 

我想知道如何爲每個動作(CRUD)引用並獲取特定Device對象的deviceType。我也不明白如何在處理我的視圖時參考相關的設備類型。

GET創建 *如何讓我的DeviceTypes的選擇列表,以便用戶可以創建一個設備,然後選擇它是什麼類型的設備? *我對View部分做了一些研究,看起來我需要使用速記Razor「@ model.SelectList()」的語法,但這些參數讓我感到困惑。我不明白它要求什麼。以下是控制器現在的操作。

public IActionResult Create() 
    { 

     return View(); 
    } 

指數 *在顯示所有設備的循環,我將如何還包括在設備的結果表中的設備類型的名字嗎? *在視圖中,我會假設我可以使用@ Html.LabelFor來顯示數據的名稱是什麼,但是如何獲得實際值?

public async Task<IActionResult> Index() 
    { 
     return View(await _context.Device.ToListAsync()); 
    } 

更新/編輯 *我怎麼會檢索設備對象設備類型,然後允許用戶編輯呢?

// GET: Devices/Edit/5 
    public async Task<IActionResult> Edit(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var device = await _context.Device.SingleOrDefaultAsync(m => m.ID == id); 
     if (device == null) 
     { 
      return NotFound(); 
     } 
     return View(device); 
    } 

刪除 *我還沒有在這看着呢,但我在這裏把它在編程的情況下其他動作時,那裏有什麼注意事項?

// GET: Devices/Delete/5 
    public async Task<IActionResult> Delete(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var device = await _context.Device 
      .SingleOrDefaultAsync(m => m.ID == id); 
     if (device == null) 
     { 
      return NotFound(); 
     } 

     return View(device); 
    } 

同樣,如果除了微軟的「用Mac和Linux構建一個帶有Visual Studio代碼的asp.net核心應用程序」外,我還可以看到其他一些資源,這將解釋如何在視圖/控制器內部的模型中引用關係,這很好。

謝謝

回答

3

首先,我假設正在這裏使用實體框架,因爲這是迄今爲止最常用的設置。

獲取deviceType

隨着EF,關係可以懶洋洋地,興致勃勃,還是明確地加載。延遲加載是自動駕駛儀的方法:當你需要時,數據只是神奇的。但是,爲了啓用延遲加載,該屬性必須爲virtual。這是因爲EF必須覆蓋該屬性以向其添加延遲加載邏輯,並且如果該屬性不是虛擬的,則不能這樣做。

public virtual DeviceType deviceType{get; set;} 

或者,您可以急於或顯式加載您的關係。顯式加載非常有所有懶惰加載沒有專業人士,所以它不是真正的建議,除非你是因爲一個特定的原因。不過,你可以做到這一點通過:

context.Entry(device).Reference(m => m.deviceType).Load(); 

最後,你可以熱切加載的關係,但這必須與初始查詢(因此,「渴望」)一起完成。

var devices = context.Devices.Include(m => m.deviceType); 

沒有做其中的一個,你的關係屬性將null

創建一個下拉列表中的設備類型

在你看來,你會很明顯地要使用Html.DropDownListFor。但是,您有一個問題,因爲您沒有要綁定的Device上的媒體資源。 select的發佈值將是一個簡單的類型,如整數ID,因此您無法將其直接綁定到像deviceType這樣的屬性。你有兩個選擇:

  1. 屬性添加到Device爲外鍵,而不是依賴隱一個EF將創建:

    public int deviceTypeId { get; set; } 
    
  2. 與像上面的屬性創建一個視圖模型。在發佈後,您會將視圖模型中的值映射到您的實體上,當涉及到deviceTypeId時,您將使用它從數據庫中提取適當的設備類型,然後使用該設置在您的實體上設置deviceType

接下來,你需要一個IEnumerable . Don't bother creating an actual SelectList`實例。剃刀可以照顧到這一點,而當你讓剃刀處理它時,事情通常會更順利。創建是相當直接:

ViewBag.DeviceTypeOptions = context.DeviceTypes.Select(m => new SelectListItem 
{ 
    Value = m.Id.ToString(), 
    Text = m.Name 
}); 

然後,在你的看法:

@Html.DropDownListFor(m => m.deviceTypeId, (IEnumerable<SelectListItem>)ViewBag.DeviceTypeOptions) 

如果你使用一個視圖模型,而不是直接的實體,這是更好地把選項對查看模型而不是ViewBag,但您可以通過任何方式完成工作。

獲取deviceType名稱

LabelFor是用於生成實際的HTML label。假設DeviceType有一個屬性Name的結果將是:

<label for="Name">Name</label> 

內部,LabelFor將調用DisplayNameFor,這是你如何獲得屬性的實際名稱(或從Display屬性的值)。那結果將只是:

Name 

你要尋找的是DisplayFor或只是簡單的@語法。以下是功能上等同並且將兩個輸出類似Some Awesome Device Type

  1. @Html.DisplayFor(m => m.Name)
  2. @Model.Name

編輯deviceType

這一個對堆棧溢出有點過於寬泛。簡而言之,您只需在窗體中爲其呈現字段,就像其他任何內容一樣。您只需要注意輸入的命名,因爲您需要維護對象層次結構。例如,如果您正在編輯一個Device,你必須輸入爲deviceType,如:

<input type="text" name="deviceType.Name" /> 

但是,只要您使用*For風格傭工,本身工作了大部分。

刪除

有算不上什麼特別的考慮這裏,作爲EF的默認值是級聯。如果由於某種原因,你決定(或者已經決定在現有的數據庫中),以便不級聯,那麼在刪除設備之前,你只需要刪除設備類型即手動做同樣的事情級聯會。

+0

EF Core尚未對延遲加載進行加載。 https://docs.microsoft.com/en-us/ef/core/querying/related-data – Alexan

+0

@Alex:是的,我忘了這一點。或者,也許我只是覺得他們已經排序了將近兩年;)。沒什麼大不了。老實說,我還沒有看到很多好的理由來延遲加載,反正。一般來說,你只需要加載你需要的一切。 –

+0

即使EF支持它,也不要在網絡應用程序中使用延遲加載,只要您可以提供幫助。這是爲什麼:http://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications – ssmith

1

獲得設備列表時,假設這是使用實體框架包括設備類型,使用包括像_context.Device.Include(d => d.DeviceType).ToListAsync()。這將會......包括您指定的關聯實體。實體框架還有很多,所以我建議在處理模型和上下文時查找更多信息。

至於你可以選擇的類型列表,你首先需要分別獲得可用設備類型的列表,然後將它傳遞給視圖(在viewbag中,或者你選擇),然後......我還沒有和MVC核心的工作很多,但我懷疑這是相當類似老版本,但無論如何像MVC6 Dropdownlist of Countries

0

首先你需要包括外鍵在您的設備型號:

public int DeviceTypeID {get; set;} 

然後你應該包括這個設備類型屬性如何answered here

_context.Device.Include(d => d.DeviceType).ToListAsync()