如何使用具有有效负载的桥接表来更新具有多对多连接的表

时间:2011-06-12 16:56:34

标签: asp.net-mvc-3 entity-framework-4 many-to-many

我正在构建个人电影目录并具有以下结构:

电影桌/实体

MovieID(PK标识符)+ 其他电影相关的属性

人员表/实体

PersonID(PK标识符)+ 其他与人有关的财产。

PersonMovie表/实体

MovieID(FK)

PersonID(FK)

其他列包含有关此人对电影所做的事情的信息(即字符名称或作业)。

我希望有一个允许用户创建/更新电影或人物的视图,并有一个复选框,然后允许他们选择现有或创建新的演员(人)或电影。

我在两条战线上挣扎: 1)如何呈现这种类型的多页数据收集。一部电影有很多演员和演员。一个人可以参与很多电影。 2)如何更新上面的2或3个表,具体取决于用户输入的内容。用户可能想要添加电影,但还不知道演员,反之亦然。用户可能想要添加电影并添加已经存在为电影演员的人。

此外,我不希望级联删除,并且一直在努力将其切换为上述实体之间的关系。

我可以轻松地使用webforms,但我正在学习MVC 3&实体框架4和我仍然围绕这一切。我环顾四周,没有遇到过我希望实现的解决方案/教程。

非常感谢任何帮助。 贝

2 个答案:

答案 0 :(得分:1)

当我从另一个MVC框架(Rails和ROR)切换时,我遇到了类似的问题。对于初学者,请查看类似问题的Leniency's reply,即;关系有效载荷或非PJT(纯连接表),遗憾的是ASP.NET MVC3不支持显式。

您可以创建ModelView(虚拟实体)来包装其他实体类型的集合并将其传递给View。上述帖子有详细的示例,其中包含Model,ViewModel,View,Partial和Controller的代码。 (阅读该帖子的答案,我的答案是Leniency在那里的答案的继续)

希望它有所帮助!

答案 1 :(得分:0)

Vulcan在正确的轨道上,我链接的回复也将帮助您获得链接表包含额外数据的模型设置。

为了构建视图,您很可能会发现ViewModel是您要描述的更复杂设置的方法,然后您的控制器和服务层将处理视图模型数据并将其转换为EF实体。 Viewmodel专门针对您需要的视图而构建,而不是尝试将域模型敲入可能不适合它的视图中。

这是创建电影的工作流程之一的一个非常艰难的开始,带有可选的人员列表。

域 - 您的电影和人物类,以及类似于what I described here.

的链接表

查看模型 - 制作电影并将人物附加到其中

public class MovieCreatePage
{
    public MovieInput Input { get; set; }  // Form field data...
    public IEnumerable<People> People { get; set; } // list of people for drop downs
    // ... other view data needed ...
}

public class MovieInput
{
    [Required, StringLength(100)]
    public string Name { get; set; }

    // Easiest to just submit a list of Ids rather than domain objects.
    // During the View Model -> Domain Model mapping, there you inflate them.
    public int[] PeopleIds { get; set; }

    // ... other input fields ...
}

Create.cshtml - 只为您的视图模型制作一个表单。

控制器:

// NOTE! The parameter name here matches the property name from the view model!
// Post values will come across as 'Input.Name', 'Input.Year', etc...
// Naming the parameter the same as the view model property name will allow
// model binding.  Otherwise, you'll need an attribute: [Bind(Prefix=".....")]
[HttpPost]
public ActionResult Create(MovieInput input)
{
    if (ModelState.IsValid)
    {
        //
        // Now do your mapping - I'd suggest Automapper to help automate it,
        // but for simplicity, lets just do it manually for now.

        var movie = new Movie
        {
            Name = input.Name,
            Actors = input.PeopleIds != null
                ? input.PeopleIds.Select(id => new Person { Id = id })
                : null
        };

        //
        // Now save to database.  Usually in a service layer, but again,
        // here for simplicity

        // First, attach the actors as stubbed entities
        if (movie.Actors != null)
        {
            foreach (var actor in movie.Actors)
                _db.People.Attach(actor);  // Attach as unmodified entities
        }

        _db.Movies.Add(movie);
        _db.SaveChanges();

        TempData["Message"] = "Success!"; // Save a notice for a successful action
        return RedirectToAction("Index");
    }

    // Validation failed, display form again.
    return View(new MovieCreatePage
    {
        Input = input,
        // ... etc ...
    });
}

希望这会帮助你一些并指出你的方向。当然,它确实提出了许多其他需要花费时间的问题(例如,自动播放器,服务层,所有各种EF问题等等)。