從上週開始,我們遇到了類似的問題,這裏有一個想法。以爲我與你分享。
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;
}
這樣的想法是,你有一個過濾器,過濾器的屬性的名稱相匹配要運行對過濾器的對象的屬性名稱。如果該屬性的值不爲空,我爲它建立一個表達式。爲了簡單起見,我僅構建Expression.Equal
表達式,但我正在考慮對其進行擴展。
你可以提供更多信息,你的輸入是如何更動態的,然後從第一個鏈接輸入數據。也許你嘗試過一個簡單的例子,希望你想實現。 – esskar