Q:

Updating many-to-many navigation property in Entity Framework 6, changes not being saved

I've been pulling my hair out for about 2 days now, as I simply cannot get EF to save changes whenever I add a many-to-many entity to an existing entity.
My structure is plain simple: 

I have a table called Person, it has an ID (Primary, identity), and a few other string fields 
A table called Keyword with an ID (Primary, identity) and a string field called Value
and a PersonKeywordRelation, with a PersonId, and a KeywordId field

When I have generated my entities (Database first), I get a class Person, with an ICollection<Keyword> - all good, works as expected.
The problem arises when I try to save an existing Person, with a modified list of keywords. Only the scalar properties (strings) are saved, not my keywords! 

I've tried disabling Lazy Loading, no effect. 
I tried loading each individual keyword from the database again, no effect.
I tried loading all keywords into the context to see if that would help EF detect changes, it didn't.

I am pretty sure I'm not the only one who have had this problem, (in fact I am entirely sure as I have seen a couple questions on here already, on the same subject, yet I am unable to find a working answer...), mostly for older versions of EF, which is another good reason as to why I started yet another question: Has nothing changed that addresses this issue at all?
Here is my code that does the updating (and creation) of persons. You'll notice my attempt on making EF save changes accordingly.
    public void SavePersons(IList<Person> persons)
    {
        // Create a EF Context
        using (var ctx = new MyDbEntities())
        {
            foreach (var person in persons)
            {
                // Attach
                ctx.Persons.Attach(person);

                // Insert or update?
                ctx.Entry(person).State = person.Id == 0 ? EntityState.Added : EntityState.Modified;

                // Get current keywords before clearing from entity
                var keywords = new List<Keyword>(person.Keywords);

                // Clear keywords from entity, so we can add fresh ones, hopefully
                // EF will have an easier time handling this..
                person.Keywords.Clear();

                // Add keywords
                keywords.ForEach(kw =>
                {
                    ctx.Keywords.Attach(kw);
                    ctx.Entry(kw).State = EntityState.Modified;
                    person.Keywords.Add(kw);
                });            
            }

            // Save
            ctx.SaveChanges();
        }
    }

A:

Finally.. Finally I can rest! I found the solution! It's not a pretty one, but it works!
Here's the code - sharing is caring.
This is definitely the last time I will work with Entity Framework. Causes more pain & agony than good.
    public void SavePersons(IList<Person> persons)
    {
        // Create a EF Context
        using (var ctx = new MyDbEntities())
        {
            // Iterate
            foreach (var person in persons)
            {
                // Get current keywords
                var keywords = new List<Keyword>(person.Keywords).ToList();

                // Fetch Person from DB (if its not a NEW entry). Must use Include, else it's not working.
                var newPerson = ctx.Persons
                                       .Include("Keywords")
                                       .FirstOrDefault(s => s.Id == person.Id) ?? person;

                // Clear keywords of the object, else EF will INSERT them.. Silly.
                newPerson.Keywords.Clear();

                // Insert or update?
                ctx.Entry(newPerson).State = newPerson.Id == 0 ? EntityState.Added : EntityState.Modified;

                // Apply new scalar values
                if(newPerson.Id != 0)
                {
                    person.Id = newPerson.Id;
                    ctx.Entry(newPerson).CurrentValues.SetValues(person);

                }

                // Iterate through all keywords
                foreach (var kw in ctx.Keywords)
                {
                    // If the current kw exists in OUR list, add it
                    // - if not, remove the relation from the DB.
                    if (keywords.Any(k => k.Id == kw.Id))
                    {
                        //ctx.Entry(kw).State = EntityState.Unchanged;
                        ctx.Keywords.Attach(kw);
                        newPerson.Keywords.Add(kw);
                    }
                    else
                        newPerson.Keywords.Remove(kw);
                }
            }

            // Save
            ctx.SaveChanges();

        }
    }

