MVC 4 - 许多一对多的关系和复选框 [英] MVC 4 - Many-to-Many relation and checkboxes

查看:187
本文介绍了MVC 4 - 许多一对多的关系和复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与ASP.NET MVC 4和实体框架工作。在我的数据库,我有一个表的订阅这将重新presents订阅公共交通工具。此订阅可以访问几个公共交通公司(这样的订阅可以有1,2,3,......公司)则是这些表之间的许多一对多的关系(我有它们之间的中间表)。

I'm working with ASP.NET MVC 4 and Entity Framework. In my database, I have a table Subscription which represents a subscription to public transports. This subscription can provide access to several public transport companies (so a subscription could have 1, 2, 3, ... companies) then it is a Many-to-Many relation between these tables (I have an intermediate table between them).

我想允许订阅创建throught将包含预订的领域的金额的和复选框现有公司的页面。每一个复选框,再presents现有公司(存储在我的数据库的公司)。

I want to allow the creation of a subscription throught a page which will contain a field Amount of the subscription and the available companies by checkboxes. Every checkbox represents an existing company (a company stored in my database).

有关如何做到这一点任何想法?我读过这 ASP.NET MVC多个复选框的,但它是不是真的有帮助。

Any idea about how to do that? I've read this ASP.NET MVC Multiple Checkboxes but it was not really helpful.

编辑:这里是我的表图

推荐答案

您开始有两个视图模型。第一个它重新presents选定的公司...

You start with two view models. The first one which represents a selected company...

public class CompanySelectViewModel
{
    public int CompanyId { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

...和第二个为订阅创建

...and the second one for the subscription to create:

public class SubscriptionCreateViewModel
{
    public int Amount { get; set; }
    public IEnumerable<CompanySelectViewModel> Companies { get; set; }
}

然后在 SubscriptionController 取值付诸行动,你从数据库中加载的公司来初始化视图模型:

Then in the SubscriptionControllers GET action you load the companies from the database to initialize the view model:

public ActionResult Create()
{
    var viewModel = new SubscriptionCreateViewModel
    {
        Companies = _context.Companies
            .Select(c => new CompanySelectViewModel
            {
                CompanyId = c.CompanyId,
                Name = c.Name,
                IsSelected = false
            })
            .ToList()
    };

    return View(viewModel);
}

现在,你有此操作的强类型的视图:

Now, you have a strongly typed view for this action:

@model SubscriptionCreateViewModel

@using (Html.BeginForm()) {

    @Html.EditorFor(model => model.Amount)

    @Html.EditorFor(model => model.Companies)

    <input type="submit" value="Create" />
    @Html.ActionLink("Cancel", "Index")
}

要获得正确呈现你介绍一个编辑模板公司复选框。它必须有名称 CompanySelectViewModel.cshtml 键,进入该文件夹查看/认购/ EditorTemplates (手动创建这样一个文件夹如果它不存在的话)。这是一个强类型的局部视图:

To get the company checkboxes rendered correctly you introduce an editor template. It must have the name CompanySelectViewModel.cshtml and goes into the folder Views/Subscription/EditorTemplates (create such a folder manually if it doesn't exist). It's a strongly typed partial view:

@model CompanySelectViewModel

@Html.HiddenFor(model => model.CompanyId)
@Html.HiddenFor(model => model.Name)

@Html.LabelFor(model => model.IsSelected, Model.Name)
@Html.EditorFor(model => model.IsSelected)

名称是POST过程中加入隐藏字段preserve名。

Name is added as hidden field to preserve the name during a POST.

显然,你要的风格的意见多一点。

Obviously you have to style the views a bit more.

现在,您的POST操作是这样的:

Now, your POST action would look like this:

[HttpPost]
public ActionResult Create(SubscriptionCreateViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        var subscription = new Subscription
        {
            Amount = viewModel.Amount,
            Companies = new List<Company>()
        };

        foreach (var selectedCompany
            in viewModel.Companies.Where(c => c.IsSelected))
        {
            var company = new Company { CompanyId = selectedCompany.CompanyId };
            _context.Companies.Attach(company);

            subscription.Companies.Add(company);
        }

        _context.Subscriptions.Add(subscription);
        _context.SaveChanges();

        return RedirectToAction("Index");
    }

    return View(viewModel);
}

而不是使用连接你也可以先装公司 VAR公司= _context.Companies.Find(selectedCompany.CompanyId); 。但随着连接您不必往返到数据库加载企业加入到集合中。

Instead of using Attach you can also load the company first with var company = _context.Companies.Find(selectedCompany.CompanyId);. But with Attach you don't need a roundtrip to the database to load the companies to be added to the collection.

编辑2 :在这个答案是<$ C $延续C>修改用同样的例子模型行动和观点。)

(Edit 2: In this answer is a continuation for the Edit actions and views with the same example model.)

修改

您的模型是不是一个真正的多对一对多的关系。你有两个一到多的关系吧。是不需要的 PublicTransportSubscriptionByCompany 实体 - 正常。如果你在做 Id_PublicTransportSubscription,Id_PublicTransportCompany 的该表中的复合主键和删除ID列 Id_PublicTransportSubscriptionByCompanyId EF将检测此表模式为许多一对多的关系,建立在每个实体申购公司之一,收集和它会创建链接表中没有实体。我的code以上将适用呢。

Your model is not really a many-to-many relationship. You have two one-to-many relationships instead. The PublicTransportSubscriptionByCompany entity is not needed - normally. If you have a composite primary key in that table made of Id_PublicTransportSubscription, Id_PublicTransportCompany and remove the id column Id_PublicTransportSubscriptionByCompanyId EF would detect this table schema as a many-to-many relationship and create one collection in each of the entities for subscription and company and it would create no entity for the link table. My code above would apply then.

如果您不想更改架构出于某种原因,你必须改变POST操作,像这样:

If you don't want to change the schema for some reason you must change the POST action like so:

[HttpPost]
public ActionResult Create(SubscriptionCreateViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        var subscription = new Subscription
        {
            Amount = viewModel.Amount,
            SubscriptionByCompanies = new List<SubscriptionByCompany>()
        };

        foreach (var selectedCompany
            in viewModel.Companies.Where(c => c.IsSelected))
        {
            var company = new Company { CompanyId = selectedCompany.CompanyId };
            _context.Companies.Attach(company);

            var subscriptionByCompany = new SubscriptionByCompany
            {
                Company = company
            };

            subscription.SubscriptionByCompanies.Add(subscriptionByCompany);
        }

        _context.Subscriptions.Add(subscription);
        _context.SaveChanges();

        return RedirectToAction("Index");
    }

    return View(viewModel);
}

这篇关于MVC 4 - 许多一对多的关系和复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆