1

I've asked the question a few different times in a few different ways and I haven't yet gotten any responses. I'm trying again because I feel like my solution is too convoluted and I must be missing something simpler to do.

Using EF 4.1, POCO, DbContext API, AutoMapper, and Razor in an MVC 3 application.

I have a many-to-many relationship between two of my entities: Proposals and CategoryTags. I can successfully map (Automapper) a Proposal to my ProposalViewModel including the collection of CategoryTags.

In my View, I use javascript to allow the user to add, update, and remove tags by dynamically creating elements, each one that stores the ID of the chosen tag.

I can successfully post my ViewModel back to my controller with it's CategoryTags collection populated (although only with the ID property for each CategoryTag).

When that ViewModel is posted back to my controller, I don't know how to get those tags from the ViewModel and add them to my Model in such a way that db.SaveChanges() updates the database properly.

The only way I've had any success is to disconnect the CategoryTags collection in mapping (by namig them differently), iterate through each tag and manually look it up in my context and then call the .add() method. This is sloppy for a number of reasons which leads me to believe I'm doing it wrong.

Can anyone offer any direction at all?

UPDATE:

For anyone who is interested, my functional code:

            Dim p As New Proposal
            Dim tempTag As CategoryTag
            p = AutoMapper.Mapper.Map(Of ProposalViewModel, Proposal)(pvm)

            db.Proposals.Attach(p)
            db.Entry(p).Collection("CategoryTags").Load()

            For Each ct In pvm.Tags
                tempTag = db.CategoryTags.Find(ct.Id)

                If tempTag Is Nothing Then
                    Continue For
                End If

                If ct.Tag = "removeMe" Then
                    p.CategoryTags.Remove(tempTag)
                    Continue For
                End If

                p.CategoryTags.Add(tempTag)
            Next


            db.Entry(p).State = EntityState.Modified
            db.SaveChanges()
            Return RedirectToAction("Index")
Ben Finkel
  • 4,753
  • 7
  • 34
  • 49

1 Answers1

4

The only working way is doing this manually - you can read full description of the problem if you want. The description is related to ObjectContext API but DbContext API is just wrapper suffering same issues (actually DbContext API suffers even more issues in this scenario and because of that I will skip solution with manually setting relationships).

In short. Once you post your data back to the controller you must create new context instance and attach your Proposal and realated CategoryTags. But after that you must inform the context about changes you did. It means you must say context which tags have been added to proposal and which have been removed. Otherwise context cannot process your changes because it doesn't do any automatic merge with data in database.

The easiest way to solve this is loading current Proposal with related CategoryTags from database (= you will have attached instances) and merge incoming data into attached object graph. It means you will manually remove and add tags based on posted values.

Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Ladislav, Thak you, that's the unfortunate answer I needed to hear. If that's the only way then so be it, I'll look forward to EF 4.2 addressing the issue.. :) – Ben Finkel May 03 '11 at 20:50
  • I answered similar questions 20+ times and after that I have to say that there probably cannot be any automatic solution for this problem. Simply if you have detached entities you must somehow say EF what did you done. It is same like if you want to do insert, update, delete manually. You must know what was deleted and what was inserted. – Ladislav Mrnka May 03 '11 at 22:41
  • I think that makes sense, it would be nice if EF had some sort of "auto reconcilier" that at least attempted to figure out based on the differences between your detached entity and what was current. I'm sorry you had to answer so many times, I had a very difficult time finding a confirmed answer on this subject one way or another. – Ben Finkel May 04 '11 at 15:13