ASP.Net,MVC实体框架,映射1到多

时间:2017-07-24 16:33:59

标签: asp.net-mvc entity-framework model-view-controller mapping

在我的项目中,我首先使用ASP.Net 4.0 Entity Framework数据库。 我有2个带有外键和View Model的Entity类,示例如下:

光纤类:

namespace fibresInTexilesMvc.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public partial class fibre
    {


        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public fibre()
        {
            this.products = new HashSet<product>();
        }

        public int FiberId { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public string Picture1 { get; set; }
        public string Description { get; set; }
        public string Advantages { get; set; }
        public string Disadvantages { get; set; }
        public string Picture2 { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<product> products { get; set; }
    }
}

产品类:

    namespace fibresInTexilesMvc.Models
{
    using System;
    using System.Collections.Generic;

    public partial class product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public string Picture { get; set; }
        public string Overview { get; set; }
        public int FiberId { get; set; }

        public virtual fibre fibre { get; set; }
    }
}

查看Model.cs

namespace fibresInTexilesMvc.ViewModels
{
    public class FibAndProdViewModel

    {
        public int FiberId { get; set; }
        public string Picture1 { get; set; }
        public string Description { get; set; }
        public string Advantages { get; set; }
        public string Disadvantages { get; set; }
        public string Picture2 { get; set; }

        public string Picture { get; set; }
        public string Name { get; set; }
    }
}

我希望在ViewModel中收到有关所选光纤和所有相关产品的详细信息。

Home Controller 中,我创建了操作方法:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using fibresInTexilesMvc.Models;
using fibresInTexilesMvc.ViewModels;


    {

            //GET: Home/FiberAndProducts/5
            public ActionResult FiberAndProducts(int? FiberId)
            {
                List<fibre> fibandprodlist = db.fibres.ToList();
                List<FibAndProdViewModel> fibandprodVmList = fibandprodlist
                            .Select(x => new FibAndProdViewModel()
                            {
                                FiberId = x.FiberId,
                                Picture1 = x.Picture1,
                                Description = x.Description,
                                Advantages = x.Advantages,
                                Disadvantages = x.Disadvantages,
                                Picture2 = x.Picture2,
                                Picture = x.products.Select(a => a.Picture).SingleOrDefault(),
                                Name = x.products.Select(a => a.Name).SingleOrDefault()
                            }).ToList();
                return View(fibandprodVmList);
            }

    }

当我在浏览中打开它时会显示以下错误: Error in program

这个错误可能与收集属性有关,例如&#39;图片&#39;和&#39;姓名&#39;当我评论这两个属性时,我可以看到桌子上的所有纤维,但它不是我需要的。我需要的是,当我按下特定光纤链接时,它应该显示另一个查看有关光纤的详细信息,并从db.products获取所有相关产品。 我不知道如何解决这个问题。 以下是:

@model IEnumerable<fibresInTexilesMvc.ViewModels.FibAndProdViewModel>

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>FiberAndProducts</title>
</head>
<body>
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.FiberId)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Picture1)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Description)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Advantages)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Disadvantages)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Picture2)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Picture)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th></th>
        </tr>

    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.FiberId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Picture1)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Advantages)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Disadvantages)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Picture2)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Picture)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
            </td>
        </tr>
    }

    </table>
</body>
</html>

最重要的是我对图片有疑问。使用自定义HTMLHelper(@ Html.Image(@ Model.Picture1))将图片路径从数据库渲染到View I&#39; m。它在“细节”中显示图片。查看,但是当我在ViewModel中使用IEnumerable时,它会向我显示Compailer Error:&#34;编译器错误消息:CS1061:&#39; IEnumerable&#39;不包含&#39; Picture1&#39;的定义没有扩展方法&#39; Picture1&#39;接受类型&#39; IEnumerable&#39;的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)&#34;。 当我有IEnumerable或ICollection时如何使用CustomHTMLHelper?

CustomHtmlHelper.cs的代码:

namespace fibresInTexilesMvc.CustomHtmlHelper
{
    public static class CustomHtmlHelper
    {
        public static IHtmlString Image(this HtmlHelper helper, string src)
        {
            //Build <img> tag
            TagBuilder tb = new TagBuilder("img");
            //Ad "src" attribute
            tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));
            //return MvcHtmlString. This class implements IHtmlString
            //interface. IHTMLString will not be html encoded.
            return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在控制器中

Picture = x.products.Select(a => a.Picture).SingleOrDefault(),
Name = x.products.Select(a => a.Name).SingleOrDefault()

应该改为

Products = x.products

在你的FibAndProdViewModel中添加

ICollection<product> Products { get; set; }

喜欢这个

namespace fibresInTexilesMvc.ViewModels
{
 public class FibAndProdViewModel
 {
    public int FiberId { get; set; }
    public string Picture1 { get; set; }
    public string Description { get; set; }
    public string Advantages { get; set; }
    public string Disadvantages { get; set; }
    public string Picture2 { get; set; }

    public string Picture { get; set; }
    public string Name { get; set; }

    ICollection<product> Products { get; set; }
 }
}

在视图中这个

<td>
  @Html.DisplayFor(modelItem => item.Picture)
</td>
<td>
  @Html.DisplayFor(modelItem => item.Name)
</td>

应该改为

<table>
 @foreach (var product in item.Products) {
 <tr>
    <td>
        @Html.DisplayFor(modelItem => product.Picture)
    </td>
    <td>
        @Html.DisplayFor(modelItem => product.Name)
    </td>
</tr>
}
</table>
相关问题