类型'System.Guid'和'System.String'之间没有定义强制运算符

时间:2016-06-16 14:14:45

标签: c# linq linq-to-sql type-conversion expression-trees

我正在为Linq-to-sql构建表达式树。在某些表的数据库中,相关列存储为string,而有些列存储为Guid。我已经解决了与intint?类似的问题,方法是将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);
    }

如何在表达式树中转换类型以匹配?

1 个答案:

答案 0 :(得分:1)

<强>解决方法1:

这比solution2快一些,但是如果你有多种可能性可能会导致长if elseswitch语句

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:

This did work

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)))