Sto costruendo un albero delle espressioni per Linq-to-sql
. Nel database su alcune delle tabelle le colonne rilevanti sono memorizzate come string
mentre alcune sono memorizzate come Guid
. Ho risolto un problema simile con int
e int?
avvolgendo la costante lambda con Expression.Convert(Expression.Constant(search.PolicyNumber), policyNumberColumnLambda.Type)
(dove PolicyNumber
volte era nullable
) che funzionava perfettamente. Ma non sembra che Guid
di convertire le string
.
Il codice sembra seguire:
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);
}
Come posso convertire i tipi in modo che corrispondano nell'albero delle espressioni?
Soluzione 1:
Questo è di una magnitudine più veloce di solution2, tuttavia se si dispone di una varietà di possibilità si potrebbe ottenere una lunga istruzione if else
o switch
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);
}
ma è incredibilmente lento in quanto produce seguendo 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)))