I am building Expression tree for Linq-to-sql
. In database on some of tables relevant columns are stored as string
while some are stored as Guid
. I have solved similar problem with int
and int?
by wrapping lambda constant with Expression.Convert(Expression.Constant(search.PolicyNumber), policyNumberColumnLambda.Type)
(where PolicyNumber
sometimes was nullable
) which worked just fine. But it does not fly for Guid
to string
conversion apparently.
Code looks following:
public static IQueryable<IRetrieveGuid> SearchByRetrieveGuid<IRetrieveGuid>(this IQueryable<IRetrieveGuid> queryable, SearchModel search)
{
var paramLambda = Expression.Parameter(typeof(IRetrieveGuid));
var columnLambda = Expression.Property(paramLambda, "retrieveguid");
var lambda = Expression.Lambda<Func<IRetrieveGuid, bool>>(
Expression.Equal(columnLambda, Expression.Convert(Expression.Constant(search.RetrieveGuid), columnLambda.Type)), paramLambda);
return queryable.Where(lambda);
}
How do I convert types to match in expression tree?
SOLUTION1:
This is by a magnitude faster than solution2, however if you have variety of possibilities might result in long if else
or switch
statement
var retrieveGuidAsString = search.RetrieveGuid.ToString();
var constantLambda = columnLambda.Type.Name == "Guid" ? Expression.Constant(search.RetrieveGuid) : Expression.Constant(retrieveGuidAsString);
var lambda = Expression.Lambda<Func<IRetrieveGuid, bool>>(Expression.Equal(columnLambda, constantLambda), paramLambda);
SOLUTION2:
public static IQueryable<IRetrieveGuid> SearchByRetrieveGuid<IRetrieveGuid>(this IQueryable<IRetrieveGuid> queryable, SearchModel search)
{
var paramLambda = Expression.Parameter(typeof (IRetrieveGuid));
var columnLambda = Expression.Property(paramLambda, "retrieveguid");
var lambda = Expression.Lambda<Func<IRetrieveGuid, bool>>(
Expression.Equal(columnLambda, Expression.Call(Expression.Convert(Expression.Constant(search.RetrieveGuid), typeof (object)), typeof (object).GetMethod("ToString"))), paramLambda);
return queryable.Where(lambda);
}
but is incredibly slow as it produces following sql
([Extent1].[retrieveguid] = 'c87d1234-46ad-47bf-9a9c-d9a35a454bd5' as uniqueidentifier) AS nvarchar(max))))) OR (([Extent1].[retrieveguid] IS NULL) AND (LOWER( CAST( cast('c87d1234-46ad-47bf-9a9c-d9a35a454bd5' as uniqueidentifier) AS nvarchar(max))) IS NULL)))