Many-to-many relationships in mvc and EF

I created a blog site where users can Post

blog, there is a many-to-many relationship between Posts

and in my model and database using the Entity Framework Tags

.

In my database I also have it PostTagMap

, but I don't see this in my EF model. Not sure what I need. PostTagMap

just contains a unique ID for Post and Tag nothing else.

(it should be noted that I created the database from the model)

In my Create Post

view (and controller), I want users to be able to create tags (along with them), making sure they are identified with each other. However, I cannot find a way to do this.

Post Model:

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>

      

Edit:

Can't use field EditorFor

for my tag Create

for tags. This is because the view is Create

bound to @Model MyBlogger.Post

.

Tags are only shown as a collection and as such if I say:

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

      

Then it shows up blank in my view when rendered.

I tried foreach

it however it didn't work. For an instance trying to do this in my view Create

:

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

      

I get an error: Object reference not set to an instance of an object.

+3


source to share


3 answers


In relation Many-to-Many

, if you use DataAnnotation

, EF will create a Many-to-Many relationship. in your case

Post class has collection navigation property for Tag

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

      

And the Tag has a collection navigation property for Publish

 public virtual ICollection<Post> Posts { get; set; }

      

Which will create a Many-to-Many relationship between the mail and the tag.




In your opinion:

There are several ways to add / get tag ID value, one way to link it to the model. Post - try the following, since you already have a link between the two models:

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

      

model.Tags

returns a collection of Tags if you need an attribute that you need to specify explicitly (e.g. Id, Name ...)

Paste into M-to-M relation:

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

      

0


source


Many of the many tables do not appear in the EF model. To add lines to it you have to do something like PostObject1.Tags.Add (TagObject1) or TagObject1.Posts.Add (PostObject1).

Here's how to do it: Insert / update many in many objects. How to do it?



To select rows, you need an EF object and access to a list of another table.

0


source


Linked (mapping) tables may not show up in the EF model, but you can easily add a new tag

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

      

As a good practice, you should create view models instead of using models directly for views,

here is a link to help you with that Link

For tags, you can either do an EditTemplate (recommended) or for a loop

Here is an example of a loop for a loop

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

      

To create a new

Just click the button Add New

and onclick

, just add a new textbox, but set the Id to Tags[i].Name

where I am the tag Count()+1

.

-1


source







All Articles