Почему предикат не фильтруется при построении с помощью отражения - PullRequest
4 голосов
/ 26 октября 2010

Я создаю довольно большой фильтр на основе объекта SearchObject, который имеет более 50 полей, в которых можно выполнять поиск.

Вместо того, чтобы создавать свое условие where для каждого из них в отдельности, я подумал, что мне нужно немного потрудиться и попытаться создать собственный атрибут, содержащий необходимую информацию, а затем использовать отражение для построения каждого из моих операторов предикатов (используя LinqKit, кстати ). Проблема в том, что код находит подходящие значения в коде отражения и успешно создает предикат для свойства, но «где» на самом деле не генерируется, и мой запрос всегда возвращает 0 записей.

Атрибут прост:

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

И это мой метод, который строит запрос:

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

SearchObject довольно прост:

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

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

Любые предложения будут с благодарностью. Я вполне могу идти в неправильном направлении и не обижусь, если у кого-то есть лучшая альтернатива (или хотя бы одна, которая работает)

1 Ответ

1 голос
/ 07 сентября 2011

Вы нигде не назначаете свой предикат.Измените строку на эту:

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