我正在为Linq-to-sql
构建表达式树。在某些表的数据库中,相关列存储为string
,而有些列存储为Guid
。我已经解决了与int
和int?
类似的问题,方法是将lambda常量与Expression.Convert(Expression.Constant(search.PolicyNumber), policyNumberColumnLambda.Type)
包裹在一起(其中PolicyNumber
有时为nullable
)。但它显然没有Guid
转换为string
转换。
代码如下:
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);
}
如何在表达式树中转换类型以匹配?
答案 0 :(得分:1)
<强>解决方法1:强>
这比solution2快一些,但是如果你有多种可能性可能会导致长if else
或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);
<强>溶液2:强>
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);
}
但是因为它产生了以下的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)))