Question

I have a blog website built using c# ASP.NET and entity framework. I am setting up a page to create a blog which allows the user to add tags. This works fine. However, when it comes to edit the blog post I am sure I must be missing a trick. I can't work out how I would update all the tags attached to the blog post in a single simple process.

The Blog and Tag entities are setup as many-to-many.

So currently I have:

_blog = blogRepo.GetBlogByID(blog.Id);
_blog.Tags = blog.Tags;
blogRepo.UpdateBlog(_blog);
blogRepo.Save();

Which works fine if I'm adding new tags. However, if I'm removing tags it only works Entity Framework side of things. As soon as the DB Context re-initialises, it picks up from the database that the tag is still attached to the blog.

E.g. I have tag "test" added to the blog. I edit the blog and remove the tag "test" and save the blog. The blog is returned by the same request with the tag list empty. If I then make another request for the blog then the tag "test" is back again.

I thought I could just remove all tags from the blog each time and then add any which are there. But I'm sure there must be a better way. Or something is set wrong and this should work in the current setup?

Any help appreciated. Particularly if it points out something stupid which I'm not seeing.

Était-ce utile?

La solution

You can't simply assign a new child list to an entities object and expect Entities to figure out all your changes. You have to do that yourself. Here's a simple way to do it. It's not the most efficient, and there are tricks to speeding this up, but it works.

First you need to get the existing list of tags. I'm assuming GetBlogByID() does this. Then, rather than assign a new list of tags, you need to call Remove() on each tag you want removed. Here's an example:

//Generate a list of tags to remove
var tagsToRemove = _blog.Tags.Except(myNewListOfTags).ToArray(); 

foreach(var toRemove in tagsToRemove)
    _blog.Tags.Remove(toRemove);

...Save changes

Now, as a optimization if there are a lot of tags, I sometimes will do a direct SQL call to delete all the many-to-many relationships, and then add them all again using Entities, rather than have to figure out each add and remove operation.

_myDbContext.Database.ExecuteSqlCommand(
    "DELETE FROM BlogTagsManyToManyTable WHERE BlogId = @BlogId",
    new SqlParameter("@BlogId", blogId));

I can then add a new list of Blog Tags without having to do any special work.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top