2011-10-13 3 views
0

Nous utilisons Entity Framework (connecteur MySQL) et créons un outil de recherche central sur notre application web.Linq to Entities Recherche Dynamique Complexe

This link est presque exactement ce dont j'ai besoin, en plus du fait qu'il utilise des entités et des propriétés prédéfinies. Dans notre scénario de recherche, nous aurons un nombre dynamique de termes et de champs de recherche (c.-à-d.: L'utilisateur choisit de rechercher le nom, la valeur et la ville, ou le fournisseur et le conseiller).

Est-il possible d'obtenir ce type de fonctionnalité avec LINQ, de sorte que nous puissions tirer parti du mécanisme de chargement différé? Je voulais vraiment éviter de générer des chaînes SQL, si possible. J'ai regardé Dynamic LINQ with Expression Trees mais je n'ai pas réussi à faire fonctionner ceci (ou this).

+0

pouvez-vous donner plus d'informations, comment votre entrée est plus dynamique que les données d'entrée de votre premier lien. peut-être un exemple rapide de ce que vous avez essayé et que vous voulez que vous vouliez accomplir. – esskar

Répondre

0

Je sais que vous avez indiqué que vous vouliez éviter de générer des chaînes SQL, mais c'est souvent le moyen le plus simple. (Beaucoup plus facile que les arbres d'expression personnalisés). Si vous faites cela dans EF, je vous recommande de vérifier Entity Sql qui fonctionne contre votre modèle conceptuel, mais permet des options d'interrogation plus dynamiques que LINQ. LINQ est vraiment adapté pour compiler des requêtes de temps plutôt que des requêtes d'exécution. Vous pouvez lire sur Entity SQL au http://msdn.microsoft.com/en-us/library/bb387145.aspx.

+0

suggérant de revenir à SQL parce que c'est juste facile, n'est pas un bon choix du tout. – esskar

+0

Je ne recommande pas de revenir à SQL, je suggère d'aller de l'avant à Entity SQL. –

0

depuis la semaine dernière, nous avons un problème similaire à faire face, voici une idée que je viens d'avoir pour cela. Je pensais que je le partage avec toi.

interface IPerson 
{    
    DateTime BirthDay { get; set; } 

    string City { get; set; }    

    string FirstName { get; set; } 

    string LastName { get; set; } 
} 

interface IFilter { } 

interface IPersonFilter : IFilter { } 

class PersonFilter : IPersonFilter 
{    
    public DateTime? BirthDay { get; set; } 

    public string City { get; set; } 

    public string FirstName { get; set; } 

    public string LastName { get; set; }    
} 

static IQueryable<TSource> ApplyFilter<TSource, TFilter>(IQueryable<TSource> source, TFilter filter) where TFilter : IFilter 
{ 
    const BindingFlags bindingFlags = BindingFlags.Public|BindingFlags.Instance|BindingFlags.GetProperty; 

    var retval = source; 
    foreach (var filterProperty in filter.GetType().GetProperties(bindingFlags)) 
    { 
     var elementParameter = Expression.Parameter(source.ElementType, "type"); 
     var elementProperty = Expression.Property(elementParameter, filterProperty.Name); 

     var value = filterProperty.GetGetMethod().Invoke(filter, null); 
     if (value != null) 
     { 
      var constantValue = Expression.Constant(value, elementProperty.Type); 
      var expression = Expression.Equal(elementProperty, constantValue); 
      retval = retval.Where(Expression.Lambda<Func<TSource, bool>>(expression, elementParameter)); 
     } 
    } 

    return retval; 
} 

L'idée est que vous avez un filtre où les noms des propriétés du filtre correspondent aux noms de propriétés de l'objet que vous souhaitez exécuter le filtre contre. et si la valeur de la propriété n'est pas nulle, je construis une expression pour elle. Pour la simplicité, je ne construis que des expressions Expression.Equal, mais je pense à l'étendre.