Tuesday, June 28, 2011

Our long national nightmare is over

Creating/editing my complex EF4 entity graph with a many-to-many relationship finally works the way I intended.  I... I'm not sure what to say.  More shock than happiness right now.

My biggest issue, as you know, was figuring out what the ObjectContext expected of me.  When to attach/detach/add/remove... it's a frustrating dance to engage in, and at times even complex.  A lot of that fumbling stemmed from my inexperience, which is part of the reason why I'm doing this.  I need to get this right, even if I go kicking and screaming.

The other problem is myself (cue: "I could've told you that").  I get tunnel vision, and I'm stubborn as a mule.  That's not a good combination.

Unsurprisingly, the solution was simple, so simple it's embarrassing.  That's something else I do - write convoluted code, and then whittle it down (again, while kicking and screaming) until the solution is a mere handful of lines.  I guess my brain needs to contort itself for a bit before discovering the right way to go.

A special shout out to Julie Lerman, who humored me both on Stack Overflow and Twitter, and who must surely think I'm some sort of psycho stalker.  Thank you.

So... maybe I can get this thing finished this month.  Whodathunkit?

Friday, June 24, 2011

AutoMapper? More like DeciptiMapper

Well, it looks like AutoMapper has a bug in its AfterMap and BeforeMap methods.  Specifically, if you try to use a loop in order to populate the destination object with values derived from the source object, the Map methods themselves are invoked multiple times.  Not cool when dealing with EF4.  I now have several copies of the same Platforms in my test db.  Yay four extra XBox 360, PS3, and PC entities!

As always, a link to SO: http://stackoverflow.com/questions/6460177/extra-iterations-in-a-foreach-in-an-automapper-map/6473451#6473451

Thursday, June 23, 2011

Same as it ever was reprise

More 'fun' with Entity Framework 4, ASP.NET MVC, and many-to-many relationships.

Change tracking in EF4 is actually pretty good.  The problem comes when you're trying to edit an existing Entity with data from an outside source.  Then, the whole thing goes to shit, and you're forced trying to figure out exactly what to do all while the system is throwing vague exceptions telling you you can't do what you want to do.  And, naturally, all of the demos/tutorials I've seen are based on moronic demoware that anyone could figure out.  No real world examples anywhere to see.

I don't feel like blowing up the project structure I have simply because EF4 is acting like a bitch.  Part of this project is so I can learn how to do things the right, professional, ideal way, which is what I'm going to do.

Even if it kills me.

Like always, a link to SO: http://stackoverflow.com/questions/6460071/ef4-problems-w-mvc-entitykey-many-to-many-relationships-etc-what-fundamental

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