C# 类型之间未定义强制运算符';System.Guid';和';System.String';
我正在为C# 类型之间未定义强制运算符';System.Guid';和';System.String';,c#,linq,linq-to-sql,type-conversion,expression-trees,C#,Linq,Linq To Sql,Type Conversion,Expression Trees,我正在为linqtosql构建表达式树。在数据库中,某些表上的相关列存储为string,而某些列存储为Guid。我用Expression.Convert(Expression.constant(search.PolicyNumber)、policyNumberColumnLambda.Type)(其中PolicyNumber有时是null)包装lambda常量,解决了int的类似问题,效果很好。但显然,它不会为Guid到string的转换而飞行 代码如下所示: public static IQu
linqtosql
构建表达式树。在数据库中,某些表上的相关列存储为string
,而某些列存储为Guid
。我用Expression.Convert(Expression.constant(search.PolicyNumber)、policyNumberColumnLambda.Type)
(其中PolicyNumber
有时是null
)包装lambda常量,解决了int
的类似问题,效果很好。但显然,它不会为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);
}
公共静态IQueryable SearchByRetrieveGuid(此IQueryable queryable,SearchModel搜索)
{
var paramLambda=Expression.Parameter(typeof(IRetrieveGuid));
var columnLambda=Expression.Property(paramLambda,“retrieveguid”);
var lambda=表达式.lambda(
Expression.Equal(columnLambda,Expression.Convert(Expression.Constant(search.RetrieveGuid),columnLambda.Type)),paramLambda);
返回可查询的位置(λ);
}
如何将类型转换为表达式树中的匹配项?解决方案1:
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);
}
这比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);
var retrieveGuidAsString=search.RetrieveGuid.ToString();
var constantLambda=columnLambda.Type.Name==“Guid”?Expression.Constant(search.RetrieveGuid):Expression.Constant(retrieveGuidAsString);
var lambda=Expression.lambda(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.Convert(Expression.Constant(search.RetrieveGuid), columnLambda.Type)), paramLambda);
return queryable.Where(lambda);
}
公共静态IQueryable SearchByRetrieveGuid(此IQueryable queryable,SearchModel搜索)
{
var paramLambda=Expression.Parameter(typeof(IRetrieveGuid));
var columnLambda=Expression.Property(paramLambda,“retrieveguid”);
var lambda=表达式.lambda(
Expression.Equal(columnLambda,Expression.Call(Expression.Convert(Expression.Constant(search.RetrieveGuid),typeof(object)),typeof(object.GetMethod(“ToString”)),paramLambda);
返回可查询的位置(λ);
}
但由于它生成以下sql,速度非常慢
([Extent1].[retrieveguid]='c87d1234-46ad-47bf-9a9c-d9a35a454bd5'作为唯一标识符)作为nvarchar(max‘‘‘‘‘)’)或([Extent1].[retrieveguid]为NULL)和(较低(CAST(CAST(CAST(作为唯一标识符的c87d1234-46ad-47bf-9C-d9a35a454bd5)作为nvarchar(max)))为NULL))
?为什么不把它作为一种交换,在linq to objects中转换成字符串呢?@DStanley在某些表中它是GUID,而在某些表中它是字符串。我正在编写一些面向方面的东西,通过接口来查询大量杂乱无章的数据库(MSSQL和Oracle),我正在使用的接口是Interface{T Property}
,所以我事先不知道类型(这可能解释为:))