Я создаю довольно большой фильтр на основе объекта 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; }
...
}
Любые предложения будут с благодарностью. Я вполне могу идти в неправильном направлении и не обижусь, если у кого-то есть лучшая альтернатива (или хотя бы одна, которая работает)