构建动态where子句,Linq To Sql

3

我正在使用EF Code First 4.2版本, 当where子句需要动态构建时,您建议采用什么样的解决方案? 同时包括Include功能也是非常必要的:

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

上面的动态条件需要查找另一个表来过滤记录: 如果我想在Linq表达式中编写它,应该是这样的:
var result = db.Set<Contact>().Where(c=>c.AccountId == _Id_param || db.Set<LinkTable>().Any(a=>a.FkFieldId == c.AccountId && a.ParentId == _Id_param)).Include("Quotes");

基本上我需要上述表达式的动态linq,因为对于不同类型,Where子句字段会发生变化(Contact只是一个例子),例如在一个模型中,FK字段可能是“AccountId”,而在另一个模型中需要是“AccountFKId”。因此,Where子句必须是动态的!

2个回答

3

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

var query = db.Set<Contact>().Include(...);

if (something) 
{
    query = query.Where(...);
}

// Other wheres

Linq是强类型的,因此你至少需要知道在Set<>调用中要使用什么类型。你可以将其定义为泛型,但不能动态(除非你准备通过反射来编写)。你可以使用动态Linq使用字符串定义where条件,但同样你至少需要知道Set<>的类型。

谢谢您的回复,不过我该如何在动态 linq 中编写此查询呢?我感觉自己对动态 linq 的了解还不够,无法将其整合起来。特别是需要在 where 子句中从另一张表进行查找的部分。 - sam360

1

更新

我成功地解决了直接修改表达式树的问题。

TomasP的博客中得到的灵感帮了很大的忙:

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

IQueryable<LinkTable> linkQuery = db.Set<LinkTable>().AsQueryable();

MethodCallExpression internalQueryWhere = Expression.Call(typeof(Queryable), "Where", new Type[] { linkQuery.ElementType }, linkQuery.Expression,Expression.Lambda<Func<LinkTable, bool>>(myfilters, new ParameterExpression[] { filterParameter })); 

linkQuery = linkQuery.Provider.CreateQuery<LinkTable>(internalQueryWhere);

Expression anyMethodExpr = Expression.Call(typeof(Queryable), "Any", new Type[] { linkQuery.ElementType }, linkQuery.Expression);

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接