Dynamic Data – GUIDs/uniqueidentifiers as primary keys

I primarily use a GUID (uniqueidentifier) as my primary key data type. You never know when you need to synchronize your data, and I’d rather be prepared by using a GUID as a unique global identifier. Anyhow, it seems that the brand new Dynamic Data (released today as part of .net 3.5 Service Pack 1) does not really support a GUID as primary key.

The Entity Framework does not pass enough meta data to the Dynamic Data. When you use DD as a simple scaffold and add a record you will be greated with a textbox to enter the primary key for your record. Not sure about you, but I don’t have a GUIDGEN method in my brain, therefore I was looking for a solution.

There some talk of adding an attribute to the column in an inherited partial class in the forum, but that isn’t an option for large numbers of tables. So I though I’d come up with a simple solution with a little help of some jQuery goodness. (I’ve been doing a lot of jQuery lately and it’s I’m really starting to enjoy Javascript!)

My idea was to allow me to create a guid via a context menu in my dynamics data project. Like this:

You can implement the solution in your app in less than 5 minutes. You need to download

Then open your dynamic data project. You need to change 2 files:

1. Open Site.Master.cs and override the OnLoad method.

public partial class Site : System.Web.UI.MasterPage
{
    protected override void OnLoad(EventArgs e)
    {
        if (Request.QueryString["genguid"] != null)
        {
            Response.Clear();
            Response.Write(Guid.NewGuid());
            Response.End();
        }
        
        base.OnLoad(e);
    }
}

2. Then go to Site.master and insert the following directly after .

<!-- Guid Fix -->
<script src="/js/jquery-1.2.6.pack.js" type="text/javascript"></script>
<script src="/js/jquery.listen-1.0.3-min.js" type="text/javascript"></script>
<script src="/js/jquery.contextmenu.r2.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
<!--
    $(document).ready(function() {
        // add a sticky listener to the click 
        // event of all input elements
        $.listen('click', 'input', function() {
            // add a ctx menu to each input box that 
            // creates a guid in the textbox
            $('input').contextMenu('ctxGuid',
            { bindings: { 'createGuid': 
                function(t) { genGuid(t); } } });    
        });
    });

    function genGuid(t) {
        $.ajax({
            url: location.href,
            type: 'GET',
            data: { genguid: 1 },
            dataType: 'text',
            timeout: 10000,
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                alert('Error fetching guid: ' + textStatus + '/' + errorThrown);
            },
            success: function(guid) {
                $('#' + t.id).val(guid);
            }
        });
    }

-->
</script>

<div class="contextMenu" id="ctxGuid" style="display:none;">
    <ul>
        <li id="createGuid">Create GUID</li>
    </ul>
</div>
<!-- End Fix -->

Voila, you can now right-click on the primary key input textbox (or any input box for that matter) and let the server create a guid.

Hope it helps!

About these ads

Entity Data Model generated from SQL 2008 and used with SQL 2005

Ok, this is of course is not a perfect scenario, because ideally my dev and test environments should be identical to my live enviroment. But anyhow, I had some troubles with Entity Framework today. After deployment my WCF services just threw exceptions (have I ever mentioned that I don’t like WCF for making everything including debugging so difficult – but that’s a different story). After I attached the debugger I finally saw what was really throwing my exceptions. It was one of my LINQ statements on the EDM, telling me:

The version of SQL Server in use does not support datatype ‘datetime2′.

Funny, I thought. Since I don’t use datetime2. It’s actually just a model imported from a SQL 2005 database to SQL 2008. But since I had generated it again from the SQL 2008 (or was it just an update, I can’t remember) it must have remembered this fact and now maps the datetime differently?

The solution in case anyone has the same problem is to open your EDMX in a file editor (or “open with…” in Visual Studio and select XML Editor). At the top you will find the storage model and it has an attribute ProviderManifestToken. This has should have the value 2008. Change that to 2005, recompile and everything works.

Hope it helps.