动态创建LINQ语句

时间:2017-11-23 17:40:25

标签: .net linq

我正在使用一个数据传输对象(名为:SearchSpec),其中有很多可以为空的bool ......

...
public bool? AL { get; set; }
public bool? TL { get; set; }
...

...使用LINQ ...

过滤表中的数据
var query = (from wv in Source select row); //Init query

if (SearchSpec.AL != null)
{
    query = (from wv in query
             where (wv.AL == SearchSpec.AL)
             select wv);
}

if (SearchSpec.TL != null)
{
    query = (from wv in query
             where (wv.TL == SearchSpec.TL)
             select wv);
}
...
return query.ToList();

......工作正常。如果bool不为null,我用它来过滤,否则我忽略它。

现在我必须使用超过50个标志来过滤一些数据,例如我的示例中的两个(AL,TL)。我可以复制并粘贴if语句50次,但这不是正确的方法......

我的想法是,使用像

这样的大型查询
var query = (from wv in Source select row); //Init query

query = (from wv in query
         where (SearchSpec.AL!=null && wv.AL==SearchSpec.AL)
         && (SearchSpec.TL!=null && wv.TL==SearchSpec.TL)
         ...
         select wv);

这似乎更好,但它仍然是复制和粘贴。

要点:有没有办法动态生成这些语句,例如通过使用反射来获取类型bool?的所有属性,然后......好吧,这是我的问题。

1 个答案:

答案 0 :(得分:0)

你想要那样的东西;

    var query = (from wv in Source select row); //Init query

    query = (from wv in query
                 select wv);

    query = CreateDynamicBoolFilter(SearchSpec, query);

    public static IEnumerable<Source> CreateDynamicBoolFilter(SearchSpec searchSpec, IEnumerable<Source> query)
    {
        //Firstly, bool? properties of searchSpech object are retrieved using reflection
        var booleanProperties = searchSpec.GetType()
                .GetProperties()
                .Where(prop => prop.PropertyType == typeof(bool?));

        foreach (var prop in booleanProperties)
        {
            var propValue = (bool?) prop.GetValue(searchSpec, null);
            if (propValue != null) // Determine to prop value is nullable, if it doesn't apply filter
            {
                var propName = prop.Name;
                query = query.Where(x => (bool?) x.GetType().GetProperties().FirstOrDefault(p => p.Name == propName)?.GetValue(x, null) == propValue);
            }
        }
        return query;
    }