Monday, September 17, 2007

Column defaults in LINQ to SQL

There's some weird behavior in LINQ to SQL Beta2 around column defaults. It seems that you have to make a choice between using a column default or having an editable value- you can't have both. For instance- a number of our tables have a CreateDate field with a column default of GETUTCDATE(). The default O/R designer behavior for this is to set IsDBGenerated = true, and ReadOnly = true. This results in a read-only property that uses the column default value of the current date/time when we insert a new row. Most of our inserts don't supply a value for CreateDate, so we get the current date/time, which is usually what we want. However, sometimes we're using the same DBML definition to migrate old data (where we'd specify a CreateDate in the past). This is where it gets problematic. The designer lets me flip that ReadOnly bit to false, and will generate a setter for CreateDate. Unfortunately, it's not usable- any value I set is ignored. Seems like it'd work fine for generated types where full change tracking is available- "not set" is distinguishable from "set to null" or "set to a value". I'm hoping this one's fixed for RTM- I've been too busy to file the bug on it.

Saturday, September 15, 2007

DataLoadOptions and non-default behavior

I guess this is a stupid developer trick, but I've made the mistake myself and have seen several others do the same. What's wrong with this code?


using(MyDataContext dc = new MyDataContext())
{
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith(m=>m.MyBars);

var query = dc.MyFoos.Where(m=>m.SomeValue == 42);

return query.ToList();
}


It's the missing "dc.LoadOptions = dlo" call. Surprising to me that the "LoadOptions" property on the DataContext doesn't just have an already-created DataLoadOptions. I'm sure there's a good reason for this (something to do with the immutability of that object and all), but it seems to be a common mistake around here anyway, and non-obvious, especially if the DataLoadOptions setter is stuck back in a DataContext factory somewhere. It's happened enough that "did you set the LoadOptions property?" has become the first question I ask when someone complains of a particular child object value being null.