Web API and Entity Framework
Wow, I can't believe how long it has been since I've blogged. This post is purely so that 3 weeks from now, when I have these same problems and Google/Bing for the answer, maybe I'll find my post first.
I've been working with the beta bits for Microsoft's Web API that shipped with the ASP.NET MVC 4 beta. (You can get more recent, nightly builds, but I haven't been doing that.) In any case, I've come across two problems that have bitten me repeatedly.
Server Generated Primary KeysThe first is a problem with how Entity Framework handles Server Generated primary keys. (This is not specific to Web API.) In my case, I'm using GUIDs and I have the server create a GUID every time a record is inserted. The problem is that EF ignores the fact that the server is supposed to be creating the GUID. The first time you insert a new record, you get a GUID with all 0's. (00000000-0000-0000-0000-000000000000) That record will actually insert, but the second time it obviously fails because the key isn't unique.
I found a good blog post about the problem here. Through additional research on StackOverflow, I finally found that Microsoft had issued a hotfix.
Once you install this hotfix, you can open your EDMX and right-click on the PKs for every entity to expose the StoreGeneratedPattern property. Once you change this to Identity for each PK, you should be able to insert records and get the server generated GUIDs.
Navigation PropertiesI wrote this blog post because I completely forgot about this problem and late last night blew away the EDMX and all the model classes in order to refresh everything after I'd made some major changes to the underlying schema. After I did that, my Web API app stopped returning any data.
When using the "ADO.NET DbContext Generator" tooling you get classes for each entity that include Navigation Properties that are declared as virtual in support of lazy loading. We're not going to use lazy loading in Web API, so we can just remove the virtual keyword and everything works fine.
You could manually edit all the classes created by the DbContext Generator, but the next time you edit the EDMX and save it, all your classes will be regenerated with the virtual keyword.
I modified the
string PropertyVirtualModifier(string accessibility)
return accessibility + (accessibility != "private" ? " virtual" : "");
I've only scratched the surface, but so far, I'm really liking Web API. These two things are the only things that have really caused a lot of pain and once I found (and then later remembered) the solutions, they haven't been so bad.