Note that there are some explanatory texts on larger screens.

plurals
  1. PONo new many to many connections are made in the database when saving an object in EF
    primarykey
    data
    text
    <p>I have a problem with my code where I try to save a many to many connection between two objects, but for some reason it doesn't get saved.</p> <p>We used the code first method to create our database, in our database we have the following entities where this problem is about:</p> <pre><code>public class Product { public int Id { get; set; } public string Name { get; set; } public virtual ICollection&lt;ProductTag&gt; ProductTags { get; set; } } public class ProductTag { public int Id { get; set; } public string Name { get; set; } public virtual ICollection&lt;Product&gt; Products { get; set; } } </code></pre> <p>The table ProductTagProducts got automatically created, which is of course just a connection table between the two.</p> <p>Now creating products works fine. We can just run the following and it will create the connnections in the ProductTagProducts table:</p> <pre><code>Product.ProductTags.Add(productTag); </code></pre> <p>To make sure no duplicate tasks are in the database, we handle the saving for it ourselves. The productTag always contains a product tag with an existing ID.</p> <p>The problem occurs when we want to edit the same or another product. There are existing tags for the product. And we use the following process to save it:</p> <pre><code>List&lt;ProductTag&gt; productTags = new List&lt;ProductTag&gt;(); string[] splittedTags = productLanguagePost.TagList.Split(','); foreach (string tag in splittedTags) { ProductTag productTag = new ProductTag(); productTag.Name = tag; productTags.Add(productTagRepository.InsertAndOrUse(productTag)); } </code></pre> <p>We split the tags by comma, that's how it is received from the HTML element. Then we define a new entity for it and use InsertAndOrUse to determine if the tag already existed. If the tag already existed, it returns the same entity but with the ID filled in, if it did not exist yet it adds the tag to the database, and then also returns the entity with ID. We create a new list to be sure that the product doesn't have duplicate Id's in there (I have tried it with adding it to the product's existing tag list directly, same result).</p> <pre><code>product.ProductTags = productTags; productRepository.InsertOrUpdate(product); productRepository.Save(); </code></pre> <p>Then we set the list to ProductTags and let the repository handle the insert or update, of course, an update will be done. Just in case, this is the InsertOrUpdate function:</p> <pre><code>public void InsertOrUpdate(Product product) { if (product.Id == default(int)) { context.Products.Add(product); } else { context.Entry(product).State = EntityState.Modified; } } </code></pre> <p>The save method just calls the context's SaveChanges method. When I edit the product, and add another tag it doesn't save the new tag. However, when I set a breakpoint on the save function I can see that they are both there: <img src="https://i.stack.imgur.com/8H8Al.png" alt="enter image description here"></p> <p>And when I open the newly added tag 'Oeh-la-la' I can even refer back to the product through it: <img src="https://i.stack.imgur.com/jy7e8.png" alt="enter image description here"></p> <p>But when the save happens, which succeeds with all other values, there are no connections made in the ProductTagProducts table. Maybe it is something really simple, but I am clueless at the moment. I really hope that someone else can give a bright look.</p> <p>Thanks in advance.</p> <p>Edit: As requested the ProductTag's InsertAndOrUse method. The InsertOrUpdate method it calls is exactly the same as above.</p> <pre><code>public ProductTag InsertAndOrUse(ProductTag productTag) { ProductTag resultingdProductTag = context.ProductTags.FirstOrDefault(t =&gt; t.Name.ToLower() == productTag.Name.ToLower()); if (resultingdProductTag != null) { return resultingdProductTag; } else { this.InsertOrUpdate(productTag); this.Save(); return productTag; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload