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");
}