简体   繁体   English

使用外键编辑/创建EF对象

[英]Editing/Creating a EF Object with Foreign keys

I am interested in the best way to deal with foreign key relationships when using ASP.NET MVC and the Entity Framework. 我对使用ASP.NET MVC和实体框架时处理外键关系的最佳方法感兴趣。

I am currently using a ViewModel to output a create and edit page (using a partial), but things don't work too well when I get to posting the data back. 我目前正在使用ViewModel输出创建和编辑页面(使用部分页面),但是当我将数据发布回去时,效果并不理想。

Before I validate my model I use the posted value from the select list to look up the foreign object and assign it to my model, but when I use UpdateModel on the edit the references end up being null, I am guessing because it is not able to bind that property correctly. 在验证模型之前,我使用选择列表中的发布值查找异物并将其分配给我的模型,但是当我在编辑中使用UpdateModel时,引用最终为null,我猜测是因为它无法正确绑定该属性。

How do people normally deal with this issue? 人们通常如何处理这个问题? Using a ViewModel to populate my dropdowns seems straigtforward enough, but I must be missing something when it comes to the edit. 使用ViewModel填充我的下拉菜单似乎很明智,但是在编辑时我一定会丢失一些东西。 Do people normally create their own binder to get around this issue? 人们通常会创建自己的活页夹来解决此问题吗?

I have tried using both strong typing and the FormCollection . 我试过同时使用强类型和FormCollection

ViewModel: ViewModel:

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; }
}

Controller: 控制器:

[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();
            }
        }

Form: 形成:

<%@ 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>
<% } %>

Let's consider ReportDeliveryMethod . 让我们考虑ReportDeliveryMethod In your view model, it's a string . 在您的视图模型中,它是一个string On your Report object, it's a ReportDeliveryMethod type. 在您的Report对象上,它是ReportDeliveryMethod类型。 Since a string can't be implicitly cast to a ReportDeliveryMethod , UpdateModel won't bind it. 由于不能将string隐式转换为ReportDeliveryMethod ,因此UpdateModel不会将其绑定。

So what are your choices? 那您有什么选择呢?

  1. Map manually, like you're doing now. 像现在一样手动映射。
  2. Bind the ID, rather than the object reference. 绑定ID,而不是对象引用。 EF 4 supports FK associations . EF 4支持FK关联 You could put ReportDeliveryMethodId in your view model instead of ReportDeliveryMethod . 你可以把ReportDeliveryMethodId在您的视图模型而不是ReportDeliveryMethod

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM