Thursday, June 2, 2011

I'll give YOU an ObjectContext! *angry fist shake*

Here's what's going on with my ASP.NET MVC 2/Entity Framework 4.0 project:

I have two VS projects in my solution.  One is the domain, which contains my EF entities and repositories, and the other is the web UI, which contains the MVC bits and pieces.  I'm trying to do things the right way, so my web UI can have references to the domain, but the domain shouldn't have references to the UI.  My repositories are injected into my controllers via Ninject interface injection.  Simple enough.

I had my Create/Edit Game code working, but it was ugly.  I was partially binding directly to a Game entity, but for the complex stuff I was passing along other form data directly to the repo's Save method, wherein I would do what I needed to do to build/rebuild the many-to-many relationship between Games and their respective Platforms.  It worked, but it was ugly, especially since it required one of my repository interfaces (remember, they're injected into the controllers by the interface, so I use that API in the controllers rather than casting them as their concrete selves) to accept extra data in order to do its job.  That seems like a layer/coupling issue to my novice senses.  I just want a nice, clean public void SaveGame(Game game) method.  So, it was both a cosmetic and design decision to bind incoming data to a DTO, and then map it to the Game entity.

The problem is now the many-to-many relationship I'm trying to (re)build between Games and Platforms is throwing ObjectContext exceptions at me, and I'm not sure why.  I'm getting two kinds of exceptions - one is telling me that my Platform entities cannot be Added to my Game because they exist in different ObjectContexts.  The other I'll explain a little later.  I've tried 'registering' a new, null Game object by Attach/AddObject-ing it to my context like so:

Controller:
Game game = new Game();
_gameRepository.RegisterGame(game);

Repository:
public void RegisterGame(Game game)
{
    _siteDB.Games.Attach(game);
}

I tried all the variants in the register method: _siteDB.Attach(game), _siteDB.Games.Attach(game), _siteDB.Games.AddObject(game).  All gave me the same exception.

When I tried Adding the Platforms by just their EntityKeys (game.Platforms.Add(new Platform { EntityKey = src.EntityKey })), I would get an exception informing me that the entities I was trying to save had EntityKeys which already matched those within the ObjectContextManager, most likely because the Platforms already exist.

So, at this point, I'm not 100% sure how to move forward.  I don't understand why my old version of attaching the entity to the context and manipulating the Platform data originally worked, but now its not.  It's almost as though my Attach/AddObject invocations are losing scope because I'm doing it through a repository interface.  Odd, and frustrating.

Code and more detail here: http://stackoverflow.com/questions/6195167/problems-trying-to-attach-a-new-ef4-entity-to-objectcontext-while-its-entity-coll

No comments:

Post a Comment