I have a simple DbFunction to convert a date string column (mm-dd-yyyy) to datetime before ordering. The DbFunction is set up in the DatabaseContext class as follows.
[DbFunction("ConvertToDateTime", "dbo")]
public static DateTime? ConvertToDateTime(string? dateString)
{
throw new NotSupportedException();
}
This is working as expected. I can now order like
query.OrderBy(x => DatabaseContext.ConvertToDateTime(x.CustomFields.Field01))
I also need to incorporate Linq.Dynamic here. But, I can't figure out how. I need something like
query.OrderBy($"DatabaseContext.ConvertToDateTime(x.CustomFields.Field{colNumber})")
Is this possible?
I tried adding a CustomTypeProvider and DynamicLinqType attribute on DatabaseContext class but no avail.
public class MyCustomTypeProvider : DefaultDynamicLinqCustomTypeProvider
{
public MyCustomTypeProvider() : base() { }
public override HashSet<Type> GetCustomTypes()
{
var types = base.GetCustomTypes();
types.Add(typeof(DatabaseContext));
return types;
}
}
I managed to do it without Linq.Dynamic by building the lambda expression dynamically
// building expression: x => DatabaseContext.ConvertToDateTime(x.CustomFields.Field##)
var param = Expression.Parameter(typeof(Entity), "x");
var member = Expression.Property(Expression.Property(param, nameof(Entity.CustomFields)), "Field" + colNumber); // colNumber = "00" to "99"
var method = typeof(DatabaseContext).GetMethod(nameof(DatabaseContext.ConvertToDateTime), [typeof(string)]);
var call = Expression.Call(method!, member);
var lambda = Expression.Lambda<Func<Entity, DateTime?>>(call, param);
if (first)
query = order.Descending
? query.OrderByDescending(lambda)
: query.OrderBy(lambda);
else
query = order.Descending
? query.ThenByDescending(lambda)
: query.ThenBy(lambda);
But, this feels so cumbersome and unreadable. This would have been so much easier if I could manage it with Linq.Dynamic.
convert a date string column (mm-dd-yyyy)that's not a date string column. That's a critical design bug. You have no idea what that string field contains, you only hope. You have no idea what04-07-2025means - July 4th or April 7th? Fix the critical bug instead of trying to cover it up. The SQL Server provider doesn't have date parsing functions for a reasonTRY_CONVERT(date,thatField,110)should work. You can index computed columns and even views. You can't index custom function cals.TRY_CONVERT(DATETIME2, @dateString)is what the db function does.TRY_CONVERT(DATETIME2, @dateString)depends on having the correct locale because it doesn't specify the style 110. In any case you were able to add a function. Can you add a view as well? That would be a better solution. If you're really certain about the contents you can extract the substrings and order by these instead of trying to parse.Substringis mapped out of the box.