【发布时间】:2011-04-30 12:18:13
【问题描述】:
我正在构建一个基于 SearchObject 的相当大的过滤器,它有 50 多个可以搜索的字段。
我认为我不会为每个单独构建 where 子句,而是尝试构建自定义属性来提供必要的信息,然后使用反射来构建我的每个谓词语句(顺便说一下,使用 LinqKit )。麻烦的是,代码在反射代码中找到了适当的值并成功地为属性构建了一个谓词,但是“where”似乎并没有真正生成,我的查询总是返回 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; }
...
}
任何建议将不胜感激。我很可能会走错方向,如果有人有更好的选择(或至少一个有效的选择),我不会生气
【问题讨论】:
-
只是一个想法。 predicate.Or 是否将相等测试中的值作为常量或引用处理?如果作为参考,那么 Where 正在寻找特定的参考,但没有找到它们。
标签: linq reflection custom-attributes