The 'ToUniversalTime' isn't mapped to a db function, which causes this problem. You can map this function using a custom function mapping and pass it to LinqMetaData, but there are other ways to solve this in this case: As the dates are already stored in UTC format, you'll get UTC date/time values from the db (as the query simply reads the values as they're coming from the db). What I find a little strange is that the let using statement doesn't fail, but when you use it in the case statement it does. I'll check that out.
To solve this more elegantly, you should use a static method which is ran during projection of the resultset:
public static class MyDateTimeFunctions
{
public static DateTime? ConvertToUTC(DateTime? toConvert)
{
return toConvert.HasValue? toConvert.Value.ToUniversalTime():toConvert;
}
}
and the query:
var q = from data in metaData.CodeGenTest
select new MyResultWithDate
{
MyDateNotNull = MyDateTimeFunctions.ConvertToUTC(data.LoadDateNotNull),
MyDate = MyDateTimeFunctions.ConvertToUTC(date.LoadDate)
};
Of course, an extension method is also possible here but that would be a bit confusing with ToUniversalTime...
(edit): the ToUniversalTime is done in-memory if the call isn't already inside a DB function call. The ?: statement you have in your projection is a CASE statement which is constructed in a DBFunction call, so the arguments of that statement, which all runs inside the DB, have to be convertable to elements which can be passed to the DB, so the ToUniversalTime call can't be ran in-memory as it's INSIDE a case statement. As there's no mapping to convert ToUniversalTime to a db construct, it runs into a problem. As L2S does things a little differently, it might be they don't run into this problem (or they added a mapping for ToUniversalTime, don't know), but in our system, due to the mix of in-memory code and db oriented code, it's not going to work out.
However the function I showed above solves it properly