mvc和EF中的多对多关系

时间:2015-04-20 21:05:01

标签: c# sql asp.net-mvc linq

我创建了一个博客网站,用户可以Post使用博客,在我的模型和数据库中使用Entity Framework,PostsTags之间存在多对多关系。

在我的数据库中,我也有PostTagMap,但我在EF模型中看不到这一点。不确定我是否需要。 PostTagMap只包含Post和Tag的唯一标识符。

  

(应该注意我从模型中创建了数据库)

在我的Create Post视图(和控制器)上,我希望用户可以选择创建标记(以及帖子),确保它们彼此标识。但是我找不到办法。

发布模型:

public partial class Post
{
    public Post()
    {
        this.Tags = new HashSet<Tag>();
    }

    public int Id { get; set; }
    public string BlogUserEmail { get; set; }
    public int CategoryId { get; set; }
    public string Title { get; set; }
    public string ShortDescription { get; set; }

    [AllowHtml]
    public string Description { get; set; }
    public string Meta { get; set; }
    public string UrlSlug { get; set; }
    public bool Published { get; set; }
    public System.DateTime PostedOn { get; set; }
    public Nullable<System.DateTime> Modified { get; set; }

    public virtual BlogUser BlogUser { get; set; }
    public virtual Category Category { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}


<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Post</legend>

        <div class="editor-label">
            @Html.HiddenFor(model => model.BlogUserEmail, User.Identity.Name)
        </div>
        <div class="editor-field">
            @Html.ValidationMessageFor(model => model.BlogUserEmail)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.CategoryId, "Category")
        </div>
        <div class="editor-field">
            @Html.DropDownList("CategoryId", String.Empty)
            @Html.ValidationMessageFor(model => model.CategoryId)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ShortDescription)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ShortDescription)
            @Html.ValidationMessageFor(model => model.ShortDescription)
        </div>

        <div class="editor-label">
            @Html.TextAreaFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.ValidationMessageFor(model => model.Description)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

修改

我无法在EditorFor视图标记中使用Create字段。这是因为Create视图绑定到@Model MyBlogger.Post

标签只显示为集合,如果我说:

@Html.EditorFor(model => m.Tags) 

然后在渲染时在我的视图中显示为空白。

我尝试了foreach,但是没有用。对于在Create视图中尝试此操作的实例:

@foreach (var item in Model.Tags)
{
    @Html.EditorFor(model => item.Name)
    @Html.EditorFor(model => item.Description)
    @Html.EditorFor(model => item.UrlSlug)
}

我收到错误:Object reference not set to an instance of an object.

3 个答案:

答案 0 :(得分:0)

EF模型中不显示多对多的表格。要向其添加行,您必须创建类似于:PostObject1.Tags.Add(TagObject1)或TagObject1.Posts.Add(PostObject1)。

以下是如何操作:Insert/Update Many to Many Entity Framework . How do I do it?

要选择行,您需要EF对象并访问另一个表的列表。

答案 1 :(得分:0)

如果您使用Many-to-Many,则DataAnnotation关系中的EF会创建多对多关系。在你的情况下

帖子类具有标记

的集合导航属性
public virtual ICollection<Tag> Tags { get; set; }

标记具有发布

的集合导航属性
 public virtual ICollection<Post> Posts { get; set; }

这将在帖子和标签之间创建多对多关系。


在您的视图中:

有几种方法可以添加/获取标记ID的值,将其绑定到模型的一种方法是尝试以下方法,因为您已经在两个模型之间建立了关系:

      <div class="editor-field">
            @Html.EditorFor(model => model.Tags.Id)
            @Html.ValidationMessageFor(model => model.Tags.Id)
        </div>

model.Tags会返回标记的集合,如果您需要明确指定的属性(例如Id,Name ...)

以M对M关系插入:

if (ModelState.IsValid)
        {
            Tag tag = new tag{id=post.Tags.Id};
            db.Tag.Attach(tag);
            db.Tag.Add(tag);
            db.Posts.Add(post);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

答案 2 :(得分:-1)

关联(映射)表可能不会显示在EF模型中,但您可以轻松添加新标记

post.Tags.add(new Tag(){ Name = ""});

作为一种好的做法您应该创建视图模型,而不是直接使用模型进行视图,

这是帮助您Link

的链接

对于标签,您可以执行EditorTemplate(推荐)或For循环

这是for循环示例

@for(var i=0;i<Model.Tags.Count();i++) { @Html.EditorFor(model => model.Tags[i].Name) }

新建

只需拥有Add New按钮和onclick,只需添加一个新文本框,但将ID设置为Tags[i].Name,其中i是代码的Count()+1