views:

22

answers:

2

I'm working on an asp.net-mvc project.

I have an Items table and a Tags table. There's also an ItemTags table made up of two columns, setup as a composite key, storing Id's from the first two tables.

Mapped to EntityFramework this latter table enables navigation between the tables.

When i add a new Tag for a specific Item i use:

db.Items.Where(id => id.Id == newItem.Id).First().Tags.Add(newTag);

My question is: What happens if the tag is already added in the Tags table, and i have another Item wanting to reuse the same tag? What happens if i have a NEW Item that uses only tags that are already in the Tags table?

Does using:

db.Items.Where(id => id.Id == newItem.Id).First().Tags.Add(newTag);

AGAIN ensure i do not have the same Tag added twice. How do i "make" just the relationship between the Tag and Item, if they are both already in the tables.

Thank you!

A: 

Entity Framework won't ensure you won't have the same tag added twice. You must check yourself. Entity Framework has no idea what you mean by "duplicate tag".

You could throw a compound key on the foreign key columns in your many to many mapper table so if the same tag is added twice an exception is thrown. You still have to deal with the exception so its almost the same amount of code as checking for duplicates manually.

jfar
Ok. Thank you for your response. I have one more thing that is not clear. If I have an Item and a Tag that are already added to their respective tables. How do I create a relationship between them?
basilmir
@basilmir Your code should work just fine. Just add the Tags to the Item.Tags collection. Reverse should work as well. Tags.Items.Add( Item )
jfar
Thank you for your response. What i'm looking for goes something like this: Tag relatedTag= new Tag{Id = 2}; Item relatedItem= new Item{Id = 10}; db.AttachTo("Tags", relatedTag); db.AttachTo("Items", relatedItem); db.SaveChanges(); Will this create the relationship between my tables and update the table in between?
basilmir
@basilmir Why don't you experiment a little. We can't go back and forth on this forever. ;)
jfar
A: 

So... Found the answer: (don't know if there are any better ways of doing this ...) It's the same Add() method that does both the "add if the item is new" and the "add if the item is already there".

foreach (var incomingTag in tagList)
            {
                if (!String.IsNullOrEmpty(incomingTag))
                {
                    //this is where we check if there is a tag with the same name in the Tags table
                    var existingTag = db.Tags.Where(dbTag => dbTag.Name == incomingTag.ToLower()).FirstOrDefault();
                    if (existingTag == null)
                    {
                        //if there is no such Tag then we create a new one and add it
                        var newTag = new Tag { Name = incomingTag };
                        db.Items.Where(id => id.Id == newItem.Id).First().Tags.Add(newTag);
                        db.SaveChanges();
                    }
                    else
                    {
                        //if there is a tag with that name we "add" the old tag and by doing this we update the relationship
                        db.Items.Where(id => id.Id == newItem.Id).First().Tags.Add(existingTag);
                        db.SaveChanges();
                    }
                }
            }
basilmir

related questions