2016-06-16 1 views
1

Je crée l'arborescence Expression pour Linq-to-sql. Dans la base de données sur certaines tables, les colonnes pertinentes sont stockées sous la forme string tandis que d'autres sont stockées sous la forme Guid. J'ai résolu le même problème avec int et int? en enveloppant la constante lambda avec Expression.Convert(Expression.Constant(search.PolicyNumber), policyNumberColumnLambda.Type) (où PolicyNumber était parfois nullable) qui a fonctionné très bien. Mais il ne vole pas pour Guid à string conversion apparemment.Aucun opérateur de contrainte n'est défini entre les types 'System.Guid' et 'System.String'

code semble suivante:

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

Comment convertir les types de correspondance dans l'arbre d'expression?

+0

Ainsi, la colonne de base de données est un guid? Pourquoi ne pas simplement l'insérer en tant que quid et le convertir en chaîne dans linq-to-objects? –

+0

@DStanley dans certaines tables, il est GUID alors que dans certains c'est la chaîne. J'écris quelque chose d'aspect orienté via des interfaces pour interroger des bases de données désorganisées massives (MSSQL et Oracle), et les interfaces que je mets sont 'Interface {T Property} 'donc je ne connais pas le type à l'avance (ceci pourrait l'expliquer:) http://stackoverflow.com/questions/37812584/putting-interface-behind-properties-with-same-name-but-different-types) –

Répondre

1

Solution1:

Ceci est d'une grandeur plus rapide que Solution2, si vous avez plusieurs possibilités pourrait entraîner à long if else ou switch déclaration

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:

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

mais est incroyablement lent car il produit suit 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)))