2010-10-26 2 views
4

Je construis un filtre assez grand basé sur un SearchObject qui a plus de 50 champs pouvant être recherchés. Plutôt que de construire ma clause where pour chacun d'entre eux, je pensais utiliser un peu de main et essayer de construire un attribut personnalisé fournissant les informations nécessaires, puis d'utiliser la réflexion pour construire chacune de mes déclarations de prédicat (Utilisation de LinqKit btw). Le problème est que le code trouve les valeurs appropriées dans le code de réflexion et construit avec succès un prédicat pour la propriété, mais le "where" ne semble pas générer réellement et ma requête renvoie toujours 0 enregistrements.Pourquoi le prédicat ne filtre pas lors de la construction par réflexion

L'attribut est simple:

[AttributeUsage(AttributeTargets.Property, AllowMultiple=true)] 
public class FilterAttribute: Attribute 
{ 
    public FilterType FilterType { get; set; } //enum{ Object, Database} 
    public string FilterPath { get; set; } 

    //var predicate = PredicateBuilder.False<Metadata>(); 
} 

Et voici ma méthode qui construit la requête:

public List<ETracker.Objects.Item> Search(Search SearchObject, int Page, int PageSize) 
{ 
    var predicate = PredicateBuilder.False<ETracker.Objects.Item>(); 

    Type t = typeof(Search); 
    IEnumerable<PropertyInfo> pi = t.GetProperties(); 
    string title = string.Empty; 

    foreach (var property in pi) 
    { 
     if (Attribute.IsDefined(property, typeof(FilterAttribute))) 
     { 
      var attrs = property.GetCustomAttributes(typeof(FilterAttribute),true); 
      var value = property.GetValue(SearchObject, null); 
      if (property.Name == "Title") 
       title = (string)value; 
      predicate.Or(a => GetPropertyVal(a, ((FilterAttribute)attrs[0]).FilterPath) == value); 
     } 
    } 

    var res = dataContext.GetAllItems().Take(1000) 
       .Where(a => SearchObject.Subcategories.Select(b => b.ID).ToArray().Contains(a.SubCategory.ID)) 
       .Where(predicate); 

    return res.ToList(); 
} 

Le searchObject est assez simple:

public class Search 
{ 
    public List<Item> Items { get; set; } 

    [Filter(FilterType = FilterType.Object, FilterPath = "Title")] 
    public string Title { get; set; } 
    ... 
} 

Toutes les suggestions être grandement apprécié. Je vais peut-être aller dans la mauvaise direction et ne prendra aucune offense si quelqu'un a une meilleure alternative (ou au moins une qui fonctionne)

+0

juste une pensée. Est-ce que predicate.Or gère la valeur du test d'égalité en tant que constante ou en tant que référence? Si comme référence, le Où cherche des références spécifiques mais ne les trouve pas. – Handcraftsman

Répondre

1

Vous n'attribuez pas votre prédicat n'importe où. Changez la ligne à ceci:

predicate = predicate.Or(a => GetPropertyVal(a, ((FilterAttribute)attrs[0]).FilterPath) == value); 
Questions connexes