0

How can I insert a model Tag that belongs to a model Post when I have the models setup like this:

Post

public class Post
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
    public Post()
    {
       Tags = new List<Tag>();
    }
}

Tag

public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
}

This question suggests to create a Post object then add Tags to the Tags collection, I couldn't get it working: Insert/Update Many to Many Entity Framework . How do I do it?

I want to add Tag to Post already in the database, how can I do that with EF. I'm new to EF.

This is what I've tried, if I send this to the API it doesn't insert any records and I can see that the new tag Id = 0 which doesn't exist in the database, but I'd think that'd cause a foreign key constraint error, not sure If I need to do something to auto generate Id for the tag:

{
    Name: "test"
}

API

[ResponseType(typeof(Tag))]
public IHttpActionResult PostTag(Tag tag)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var post = new Post();
    var tags = new List<Tag>();
    tags.Add(tag);

    post.Tags.Add(tag);
    post.Id = 10;
    db.Entry(post).State = EntityState.Modified;
    db.SaveChanges();

    return CreatedAtRoute("DefaultApi", new { id = tag.Id }, tag);
}
matt
  • 659
  • 2
  • 8
  • 15
  • What insert code tried ? please provide insert code – Aria Dec 30 '18 at 12:06
  • You want add Tag to Post which is already in DB, you mean there is a tag in DB you want to add it to a Post ? – Aria Dec 30 '18 at 12:12
  • there is only a Post with Id = 10 in the database, now I want to add a Tag so the order would be insert Tag then insert PostTag I think – matt Dec 30 '18 at 12:25

1 Answers1

0

I fetch the Post first add then save changes.

[ResponseType(typeof(Tag))]
public IHttpActionResult PostTag(TagDTO tagDTO)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var post = db.Posts.Find(TagDTO.PostId);
    post.Tags.Add(new Tag() { Name = tagDTO.Name });            
    db.SaveChanges();

    return CreatedAtRoute("DefaultApi", new { id = post.Tags.First().Id }, post);
}
matt
  • 659
  • 2
  • 8
  • 15
  • What is the difference between this and my posted answer below ? – Aria Dec 30 '18 at 13:55
  • you add the tag twtice – matt Dec 30 '18 at 13:55
  • No if you look at the code clearly I mentioned that "think about comment in code." which is showing you if there is an already exist `Post` it just enough to find it by `context.Posts.SingleOrDefault(x => x.Id == 4);` that `4` can be your post `id` which is `TagDTO.PostId` anyway your code is the same thing that I mentioned! – Aria Dec 30 '18 at 13:59
  • what is your opinion about this paragraph "let me explain a little if you want to assign a tag to exist post you should find that `Post` firstly then add a tag to it, if that tag does exist in DB a relation will be made between `Tag` and found `Post` if that `Tag` does not exist then Tag will be inserted to DB" ? – Aria Dec 30 '18 at 14:09
  • 1
    Your error here is that you don't have a many-to-many relationship. You're *duplicating* tags because each Post has its own collection of tags. You should configure it as many to many and then join existing Posts and *existing* tags as in @Aria's code. That will create junction records in the database in something like a PostTag table. – Gert Arnold Dec 30 '18 at 15:29
  • @GertArnold, Thanks, anyway there is answer in details [Here](https://stackoverflow.com/questions/53976010/entity-framework-inserting-model-with-many-to-many-mapping/53976227#53976227) and the other one here as you can see, but it seems the problem was something else in his/her opinion. – Aria Dec 30 '18 at 15:38
  • OK, well, I see all this has turned into a bit of a mess based on false assumptions. That means that this question & answer better be discarded altogether. OP's mapping in the former question (with this empty `.WithMany()`) is correct, that's a valid and correct many-to-many mapping. Your answer there incorrectly states that the `Posts` collection is required. Adding existing tags to Post.Tags is enough to create PostTag entries. Fortunately, you can easily correct this to turn your answer into a valid answer. – Gert Arnold Dec 30 '18 at 15:49
  • @Aria See my comment above (forgot to ping you). – Gert Arnold Dec 30 '18 at 16:24
  • @GertArnold, In the past question, the question was not clear, after some chat I did understand what was OP want, anyway the important think is that the OP can solve the problem and get the clue by discussion. – Aria Dec 31 '18 at 06:00
  • The answer moved to main question https://stackoverflow.com/questions/53976010/entity-framework-inserting-model-with-many-to-many-mapping/53976227#53976227 as new update. – Aria Dec 31 '18 at 06:12