C# mvc和EF中的多对多关系

C# mvc和EF中的多对多关系,c#,sql,asp.net-mvc,linq,C#,Sql,Asp.net Mvc,Linq,我已经创建了一个博客网站,用户可以发布一个博客,在我的模型和数据库中使用实体框架,在发布和标记之间存在多对多关系 在我的数据库中,我也有PostTagMap,但是我在EF模型中没有看到这一点。不知道我是否需要。PostTagMap只包含Post和Tag的唯一标识符,没有其他内容 (应该注意的是,我从模型中创建了数据库) 在我的Create Post视图(和控制器)上,我希望用户可以选择创建标签(以及那里的帖子),确保它们相互识别。然而,我找不到一个方法来做到这一点 发布模型: public pa

我已经创建了一个博客网站,用户可以
发布
一个博客,在我的模型和数据库中使用实体框架,在
发布
标记
之间存在多对多关系

在我的数据库中,我也有
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>
然后在渲染时,它在我的视图中显示为空白

我尝试了一个
foreach
,但是没有成功。例如,在我的
Create
视图中尝试此操作:

@foreach (var item in Model.Tags)
{
    @Html.EditorFor(model => item.Name)
    @Html.EditorFor(model => item.Description)
    @Html.EditorFor(model => item.UrlSlug)
}
我得到错误:
对象引用未设置为对象的实例。

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

post.Tags.add(new Tag(){ Name = ""});
作为一种良好的做法,您应该创建视图模型,而不是直接将模型用于视图

这里有一个链接可以帮你解决这个问题

对于标记,您可以执行EditorTemplate(推荐)或For loop

下面是for循环的例子

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


只需使用
addnew
按钮和
onclick
,只需添加一个新的文本框,但将Id设置为
Tags[i]。Name
,其中i是标签的
Count()+1

多对多表不显示在EF模型中。要向其中添加行,您必须创建如下内容:PostObject1.Tags.Add(TagObject1)或TagObject1.Posts.Add(PostObject1)

以下是如何做到这一点:


要选择行,您需要EF对象并访问其他表的列表。

在多对多关系中,如果您使用的是
DataAnnotation
EF将创建多对多关系。就你而言

Post类具有标记的集合导航属性

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

如何在视图中执行此操作@Html.EditorFor(model=>model.Tags)在呈现时不显示字段?我还想让用户在视图中设置名称,而不是硬编码。哦,我明白了,这是完全不同的动物,我建议添加标记视图模型,只包含您希望用户编辑/更改的属性。如果我使用
@foreach(Model.Tags中的var-genre),您可以为标记视图模型编写一个EditorTemplate{@Html.EditorFor(model=>genre.Name)}
如何在代码中使用它来链接post?无法对集合应用索引,而且我的foreach方法也不起作用,未设置为对象的实例请初始化Tags=new List();在post类中的构造函数中是的,但是如何在我的post Create视图中实现这一点?如何获取标记id?目前我无法访问model=>m.tag EditorFor,因为标记只是@model MyBlogger.post View中的一个集合。我看到您的下拉菜单没有填充任何值。您也需要用于此的代码吗?不,标记s需要由用户创建。稍后,我会为其他想要使用相同标记的用户提供一个下拉菜单。我有一个类别的下拉菜单,它可以作为一对多关系,但Post和标记是多对多的,我看不到任何方法。我将在代码中处理创建url slug和标记的描述d也是。但我的创建视图无法使用EditorFor作为标记…我的下拉列表对于类别很好…但这与标记不同。在创建视图中,您需要添加多少标记?仅添加一个?很难理解您在这里要求的内容;
EditorFor
在这种情况下没有意义;我怀疑您需要什么“想要”类似于这样一种情况:你有一个框来输入标签,然后可以动态添加标签(如果它不存在),或者关联它(如果它已经存在);如果没有至少一些JavaScript,你就无法真正做到这一点。是的,我正在寻找一个愚蠢的版本。我想要的只是一个文本框来向帖子添加标签。t他不是一个问题,更多的是mvc和实体框架的问题。多对多关系不可能实现。不是不可能实现,只是需要更多的分析思考。为什么不在表单中将一个文本框绑定到一个字符串,您可以解析该字符串,然后在服务器端进行查找?基本上我认为最重要的是什么ese的答案试图表明,您可能无法在客户端完成此操作,而需要在服务器端完成。是的,我在这里浪费了宝贵的时间,那些试图帮助您的人也是如此:(请随意添加答案)。
public virtual ICollection<Tag> Tags { get; set; }
 public virtual ICollection<Post> Posts { get; set; }
      <div class="editor-field">
            @Html.EditorFor(model => model.Tags.Id)
            @Html.ValidationMessageFor(model => model.Tags.Id)
        </div>
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");
        }