views:

329

answers:

1

The following code tries to create a new record and then modify it after it has been committed to the database. The last SubmitChanges() call throws a ChangeConflictException.

ItemA itemA = new ItemA();
itemA.Foo = "a";
itemA.Created = DateTimeOffset.Now.UtcDateTime;

ItemAs.InsertOnSubmit(itemA);
SubmitChanges();

itemA.Foo = "b";
SubmitChanges();

By examining the dataContext.ChangeConflicts I found that the 'Created' column was in conflict, even though the reported CurrentValue and DatabaseValue appeared identical. On closer inspection I found that the Ticks were slightly different. Because I have set the DateTimeOffset column in the database to have a scale of 3, i.e. to the milli second, it is not the same as .NET's version of the value which I believe has a scale of 7. As a result Linq to Sql notices the mismatch and thinks that between the insert and update shown above, something has modified the database.

Aside from writing an extentension method or something that I can use to modify the precision in .NET is there a better way to deal with this?


Update

I have had to rely on an extension method which must be called when setting DateTimeOffset columns on the model.

public static DateTimeOffset ToUniversalTime(this DateTimeOffset dto, int scale) {
    DateTimeOffset utc = dto.ToUniversalTime();
    return utc.AddTicks(-(utc.Ticks % (int)Math.Pow(10, 7 - scale)));
}

Which can then be called as:

EntityFoo.Created = DateTimeOffset.Now.ToUniversalTime(3)

I don't really like this approach as it means I have to manually set the scale which I believe the data context should be doing.

+1  A: 

As you're always using Universal Time, I can't see what advantage DateTimeOffset gives you over DateTime. You could use DateTime.UtcNow, which has the same precision as Sql Server's DateTime.

Alternatively, as you're using Sql Server 2008, you could store your field as a DateTime2 in the database: this has the additional accuracy you require.

teedyay
I have other reasons for using the DTO, I'm surprised that the L2S designer doesn't handle it better...
Brehtt