构建动态where子句,Linq To Sql

我首先使用EF Code 4.2,当where子句需要动态构建时,你建议采用什么样的解决方案? 然而,包含function非常需要:

var results = db.Set.Where("dynamic conditions").Include("...."); 

上面的动态条件需要查找到另一个表来过滤记录:如果我想在Linq表达式中编写它,它将类似于:

 var result = db.Set().Where(c=>c.AccountId == _Id_param || db.Set().Any(a=>a.FkFieldId == c.AccountId && a.ParentId == _Id_param)).Include("Quotes"); 

我基本上需要上面表达式的动态linq,因为对于不同类型的Where子句字段更改(Contact只是一个示例),例如在一个Model中,FK字段可能是“AccountId”,而在另一个Model中,它需要是“AccountFKId” ”。 所以Where子句必须是动态的!

IQueryable是可组合的,因此您可以动态构建查询:

 var query = db.Set().Include(...); if (something) { query = query.Where(...); } // Other wheres 

Linq是强类型的,所以你总是至少要知道你将在Set<>调用中开始使用什么类型。 你可以把它变成通用但不是动态的(除非你要通过reflection整体写出来)。

您可以使用动态linq来定义带有字符串的条件,但同样您至少必须知道Set<>类型。

UPDATE

我能够通过直接修改表达式树来解决问题。

使用TomasP博客的想法帮助了很多:

关键是为内部查询创建第二个IQueryable,然后将其作为表达式传递给现有动态模型的IQueryable表达式。

 IQueryable linkQuery = db.Set().AsQueryable(); MethodCallExpression internalQueryWhere = Expression.Call(typeof(Queryable), "Where", new Type[] { linkQuery.ElementType }, linkQuery.Expression,Expression.Lambda>(myfilters, new ParameterExpression[] { filterParameter })); linkQuery = linkQuery.Provider.CreateQuery(internalQueryWhere); Expression anyMethodExpr = Expression.Call(typeof(Queryable), "Any", new Type[] { linkQuery.ElementType }, linkQuery.Expression); 

现在,您可以将anyMethodExpr传递给原始Entity的IQueryable where子句。