动态where子句的最简单方法

时间:2013-04-06 22:33:02

标签: c# entity-framework lambda linq-to-entities

在EF中生成动态where子句时,我遇到信息过载。一些解决方案看起来非常过时(我的目标是使用EF 5的.NET 4.5)。

这就是我所拥有的:

public enum PersonTypes
{
    Lazy = 1,
    Awesome = 2,
    SuperHero = 3
}

public bool IncludeLazyPeople { get; set; }
public bool IncludeAwesomePeople { get; set; }
public bool IncludeSuperHeroPeople { get; set; }

使用EF我需要查询与提供的bools匹配的人物类型。

我调查了这个: http://www.albahari.com/nutshell/predicatebuilder.aspx

这就是我想出来的:

// create an expression that would include none of the person types
var personTypeExpression = PredicateBuilder.False<DAL.Models.Person>();

if (IncludeLazyPeople)
    personTypeExpression = personTypeExpression.Or(person => person.PersonType == (int)PersonTypes.Lazy);

if (IncludeAwesomePeople)
    personTypeExpression = personTypeExpression.Or(person => person.PersonType == (int)PersonTypes.Awesome);

if (IncludeSuperHeroPeople)
    personTypeExpression = personTypeExpression.Or(person => person.PersonType == (int)PersonTypes.SuperHero);

// filter the people for all included types
var filteredPeople = ctx.People.Where(personTypeExpression);

由于我没有包含AsExpandable扩展名,因此无效。在我尝试之前,我想知道是否有更简单的方法?

2 个答案:

答案 0 :(得分:0)

var query = context.People.AsQueryable();

if (IncludeLazyPeople)
    query = query.Where(person => person.PersonType == (int)PersonTypes.Lazy);

if (IncludeAwesomePeople)
    query = query.Where(person => person.PersonType == (int)PersonTypes.Awesome);

if (IncludeSuperHeroPeople)
    query = query.Where(person => person.PersonType == (int)PersonTypes.SuperHero);

如果您只需要AND逻辑,则可以在查询中调用其他Where()方法。否则,如果您需要更强大的选项,请使用谓词构建器或System.Linq.Expressions

答案 1 :(得分:0)

ParameterExpression p = Expression.Parameter(typeof(Person));
Expression personType = Expression.MakeMemberAccess(p, typeof(Person).GetProperty("PersonType"));
Expression personTypeExpression = Expression.Constant(false);
if (IncludeLazyPeople)
    personTypeExpression = Expression.OrElse(personTypeExpression, Expression.Equal(personType, Expression.Constant((int)PersonTypes.Lazy)));

//... same as above only with different Constant values

// filter the people for all included types
var filteredPeople = ctx.People.Where(Expression.Lambda<Func<Person,bool>>(personTypeExpression,p));

这应该大致完成你想要的。没有检查编译器,希望没有太多错别字。