2011-01-10 99 views
1

我對使用ASP.NET MVC和實體框架時處理外鍵關係的最佳方式感興趣。使用外鍵編輯/創建EF對象

我目前正在使用ViewModel來輸出一個創建和編輯頁面(使用部分),但是當我發佈數據時,事情並不奏效。

在我驗證我的模型之前,我使用選擇列表中的發佈值來查找異物並將其分配給我的模型,但是當編輯時使用UpdateModel引用最終爲空,我猜測是因爲它無法正確綁定該屬性。

人們通常會如何處理這個問題?使用ViewModel來填充我的下拉菜單似乎足夠直接,但是在編輯時我必須缺少一些東西。人們通常會創建自己的綁定器來解決這個問題嗎?

我曾嘗試使用強打字和FormCollection

視圖模型:

public class ReportViewModel 
{ 
    public Report Report { get; set; } 
    public SelectList ReportDeliveryMethods { get; set; } 
    public string ReportDeliveryMethod { get; set; } 
    public SelectList ReportReceivers { get; set; } 
    public string ReportReceiver { get; set; } 
    public SelectList PermitTypes { get; set; } 
    public string PermitType { get; set; } 
} 

控制器:

[HttpPost]   
public ActionResult Edit(int id, FormCollection collection) 
     { 
      Report report; 

      try 
      { 
       report = repository.GetReport(id); 

       // Convert ReportDeliveryMethod to Object Reference       
       if (!string.IsNullOrEmpty(collection["ReportDeliveryMethod"])) 
       { 
        int reportDeliveryMethodId = 0; 
        if (int.TryParse(collection["ReportDeliveryMethod"], out reportDeliveryMethodId)) 
        { 
         report.ReportDeliveryMethod = repository.GetReportDeliveryMethod(reportDeliveryMethodId); 
        } 
       } 

       // Convert ReportReceiver to Object Reference    
       if (!string.IsNullOrEmpty(collection["ReportReceiver"])) 
       { 
        int reportReceiverId = 0; 
        if (int.TryParse(collection["ReportReceiver"], out reportReceiverId)) 
        { 
         report.ReportReceiver = repository.GetReportReceiver(reportReceiverId); 
        } 
       } 

       // Convert PermitType to Object Reference    
       if (!string.IsNullOrEmpty(collection["PermitType"])) 
       { 
        int permitTypeId = 0; 
        if (int.TryParse(collection["PermitType"], out permitTypeId)) 
        { 
         report.PermitType = repository.GetPermitType(permitTypeId); 
        } 
       } 

       if (ModelState.IsValid) 
       { 
        UpdateModel(report); 
        repository.Save(); 

        return RedirectToAction("Index"); 
       } 
       else 
       { 
        return View(); 
       } 
      } 
      catch (Exception ex) 
      { 
       return View(); 
      } 
     } 

形式:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<PermitLookup.Models.ReportViewModel>" %> 
<% using (Html.BeginForm()) 
    {%> 
<%: Html.ValidationSummary(true) %> 
<fieldset> 
    <legend>Fields</legend> 
    <div class="editor-label"> 
     <%: Html.LabelFor(model => model.Report.ShareName) %> 
    </div> 
    <div class="editor-field"> 
     <%: Html.TextBoxFor(model => model.Report.ShareName) %> 
     <%: Html.ValidationMessageFor(model => model.Report.ShareName)%> 
    </div> 
    <div class="editor-label"> 
     <%: Html.LabelFor(model => model.Report.Description) %> 
    </div> 
    <div class="editor-field"> 
     <%: Html.TextBoxFor(model => model.Report.Description)%> 
     <%: Html.ValidationMessageFor(model => model.Report.Description)%> 
    </div> 
    <div class="editor-label"> 
     <%: Html.LabelFor(model => model.Report.Frequency)%> 
    </div> 
    <div class="editor-field"> 
     <%: Html.TextBoxFor(model => model.Report.Frequency)%> 
     <%: Html.ValidationMessageFor(model => model.Report.Frequency)%> 
    </div> 
    <div class="editor-label"> 
     <%: Html.LabelFor(model => model.Report.SendTime)%> 
    </div> 
    <div class="editor-field"> 
     <%: Html.TextBoxFor(model => model.Report.SendTime)%> 
     <%: Html.ValidationMessageFor(model => model.Report.SendTime)%> 
    </div> 
    <div class="editor-label"> 
     <%: Html.LabelFor(model => model.Report.ReportDeliveryMethod)%> 
    </div> 
    <div class="editor-field"> 
     <%=Html.DropDownListFor(model => model.ReportDeliveryMethod, Model.ReportDeliveryMethods)%> 
     <%: Html.ValidationMessageFor(model => model.Report.ReportDeliveryMethod)%> 
    </div> 
    <div class="editor-label"> 
     <%: Html.LabelFor(model => model.Report.ReportReceiver)%> 
    </div> 
    <div class="editor-field"> 
     <%=Html.DropDownListFor(model => model.ReportReceiver, Model.ReportReceivers)%> 
     <%: Html.ValidationMessageFor(model => model.Report.ReportReceiver)%> 
    </div> 
    <div class="editor-label"> 
     <%: Html.LabelFor(model => model.Report.PermitType)%> 
    </div> 
    <div class="editor-field"> 
     <%=Html.DropDownListFor(model => model.PermitType, Model.PermitTypes)%> 
     <%: Html.ValidationMessageFor(model => model.Report.PermitType)%> 
    </div> 
    <p> 
     <input type="submit" value="Save" /> 
    </p> 
</fieldset> 
<% } %> 

回答

1

讓我們考慮ReportDeliveryMethod。在您的視圖模型中,這是一個string。在你的Report對象上,它是一個ReportDeliveryMethod類型。由於string不能隱式轉換爲ReportDeliveryMethod,因此UpdateModel將不會綁定它。

那麼你的選擇是什麼?

  1. 手動映射,就像你現在正在做的一樣。
  2. 綁定ID,而不是對象引用。 EF 4支持FK associations。您可以將ReportDeliveryMethodId放在您的視圖模型中,而不是ReportDeliveryMethod
+0

非常感謝Craig,這已經清除了我在Create上的問題,並且您的其他一些答案將對更新有用! – 2011-01-11 16:20:26