Adding an Many-to-Many Element in an Entity Structure

When trying to add an element with a many-to-many relationship, a primary key violation error occurs:

I have two classes - Articles and Tags that are relevant to many to many:

public class Article { public int ID { get; set; } public string Text { get; set; } public ICollection<Tag> Tags { get; set; } } public class Tag { [Key] public string UrlSlug { get; set; } public string Name { get; set; } public ICollection<Article> Articles{ get; set; } } 

When I add a new article, I allow the user to enter any tags, and then I want to create a new tag if the tag is not already created in the database, or add the tag to the tag collection of the Article object if the tag already exists. exists.

Therefore, when I create a new Article object, I call the following function:

 public static Tag GetOrLoadTag(String tagStr) { string tagUrl = Tag.CreateTagUrl(tagStr); var db = new SnippetContext(); var tagFromDb = from tagdummy in db.Tags.Include(x => x.Articles) where tagdummy.UrlSlug == tagUrl select tagdummy; if (tagFromDb.FirstOrDefault() != null) { return tagFromDb.FirstOrDefault(); } else { //create and send back a new Tag } } 

This function basically checks if there is an available tag in the database, and if so, returns that tag, which is then added to the tag collection of the Article object using article.Tags.Add ().

However, when I try to save this using the code below, I get a Violation of PRIMARY KEY error message

  db.Entry(article).State = EntityState.Modified; db.SaveChanges(); 

I can't figure out how I should just create a relationship between an article and an existing tag.

+9
c # exception exception-handling entity-framework primary-key
source share
2 answers

Use the same instance of context for the entire processing of your operation, and your life will be much simpler:

 using (var ctx = new MyContext()) { Article article = ctx.Articles.Single(a => a.Id == articleId); Tag tag = ctx.Tags.SingleOrDefault(t => t.UrlSlug == tagUrl); if (tag == null) { tag = new Tag() { ... } ctx.Tags.AddObject(tag); } article.Tags.Add(tag); ctx.SaveChanges(); } 

If you do not want to download the article from the database (this request is redundant, if you know that this article exists), you can use:

 using (var ctx = new MyContext()) { Article article = new Article() { Id = articleId }; ctx.Articles.Attach(article); Tag tag = ctx.Tags.SingleOrDefalut(t => t.UrlSlug == tagUrl); if (tag == null) { tag = new Tag() { ... } ctx.Tags.AddObject(tag); } article.Tags.Add(tag); ctx.SaveChanges(); } 
+17
source share

How are you going to create new tags? And how do you attach an existing or created object to the article.

Use something like

 Article a = new Article(...); a.tags.add(GetOrLoadTag("some tag")); 

Read this article http://thedatafarm.com/blog/data-access/inserting-many-to-many-relationships-in-ef-with-or-without-a-join-entity/

0
source share

All Articles