Entity Framework – Timestamps and Concurrency

Someone asked me today how you’d go about ensuring that timestamp columns in your database tables show up in your Entity Framework EDMX file with a Concurrency=Fixed attribute on them.

That is – it’s very likely that the timestamps are there on the table to enforce concurrency so why not default their Concurrency value to “Fixed” ?

It’s a good question but it’s not something that the tooling does as far as I’m aware so I tried to have together some LINQ to XML code that would make an attempt at it. I don’t claim that this is correct at all but it might be a starting point for this and similar, related pre-processing that you want to do on an EDMX file.

  static void Main(string[] args)
  {
    XElement edmxFile = XElement.Load(args[0]);

    XNamespace edmxNs = XNamespace.Get("http://schemas.microsoft.com/ado/2007/06/edmx");
    XNamespace ssdlNs = XNamespace.Get("http://schemas.microsoft.com/ado/2006/04/edm/ssdl");
    XNamespace mapNs = XNamespace.Get("urn:schemas-microsoft-com:windows:storage:mapping:CS");
    XNamespace csdlNs = XNamespace.Get("http://schemas.microsoft.com/ado/2006/04/edm");

    var timestampCols =
      from ssdlProp in edmxFile.DescendantsAndSelf(ssdlNs + "Property")
      join mapProp in edmxFile.DescendantsAndSelf(mapNs + "ScalarProperty")
      on (string)ssdlProp.Attribute("Name") equals (string)mapProp.Attribute("ColumnName")       
      join csdlProp in edmxFile.DescendantsAndSelf(csdlNs + "Property")
      on (string)mapProp.Attribute("Name") equals (string)csdlProp.Attribute("Name")
      where (string)ssdlProp.Attribute("Type") == "timestamp" && 
        (string)mapProp.Parent.Attribute("StoreEntitySet") == (string)ssdlProp.Parent.Attribute("Name") &&
        (string)mapProp.Ancestors(mapNs + "EntitySetMapping").First().Attribute("Name") 
          == (string)csdlProp.Parent.Attribute("Name")
      select csdlProp;

    foreach (var item in timestampCols)
    {
      item.SetAttributeValue("ConcurrencyMode", "Fixed");
    }
    edmxFile.Save(args[0]);
  }

I then used this inside of VS as a pre-build action to change my EDMX file prior to building the whole project. Seemed to work for my trivial example.

Feel free to take, borrow, tweak, ignore šŸ™‚ Just don’t blame me ( of course ) if it breaks your EDMX file.