Fluent CRUD with NHibernate ASP.NET MVC

爱⌒轻易说出口 提交于 2020-01-05 21:12:53

问题


ASP.NET MVC makes it really easy to create editing templates for simple, flat objects. But managing CRUD for complex objects with several indirections when using something like Fluent NHibernate, is not so obvious.

Example

To illustrate my question with a simple Invoice manager, Invoice entities have a Project property:

public class Invoice
{
    ...
    Project Project { get; set; } // where Project class has an Id and a Name
}

...which is mapped to the Projects table via Fluent NHibernate in my InvoiceMap:

References(x => x.Project).Inverse();

In the past, my Invoice entities would have a ProjectId property that referenced a project in my database, which made it easier to render a select list with Project IDs, but harder to output views, e.g.:

public class Invoice
{
    ...
    Guid ProjectID { get; set; }
}

But since I started using Fluent NHibernate, I don't want to dirty up my controller with more IDs.

InvoiceController

[HttpGet]
public ActionResult Edit(Guid id)
{
    var invoice = _unitOfWork.CurrentSession.Get<Invoice>(id);
    return View(invoice);
}

[HttpPost]
public ActionResult Edit(Invoice invoice)
{
    /* How to deal with invoice.Project mapping here without introducing a second
       action parameter, e.g. Guid projectId ? */

    _unitOfWork.CurrentSession.SaveOrUpdate(invoice);
    _unitOfWork.Commit();

    return RedirectToAction("Details", new { id = invoice.Id });
}

The referenced Project should not be editable from my Invoice/Edit.cshtml view, but I want to be able to choose which Project the Invoice should belong to.

How should I design my views and controllers to make CRUD easy without cluttering up my controller action with reference IDs that are not flat entity fields?


回答1:


I'd suggest you create an action on your ProjectController (assuming you have one) which has a partial view which is simply a list of the projects.

e.g.

 public class ProjectController : Controller
 {
      public ActionResult ProjectsList()
      {   
          var projects = GetAllProjects();
          return View(projects);
      }
 }

Project/ProjectsList.cshtml

@model IEnumerable<MyProject.Data.Models.Project>
@{ Layout = null }
<select name="project">
 @foreach(var project in Model)
 {
   <option value="@project.Id">@project.Name</option>
 } 
</select>

Invoice/Edit.cshtml

<label>Title</label>
<input name="title" />

@Html.Action("ProjectsList","Project")

I would then change you Edit invoice to take an input model rather than the straight invoice and look up the project by Id in that action.

HTH



来源:https://stackoverflow.com/questions/5635588/fluent-crud-with-nhibernate-asp-net-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!