构建动态 where 子句,Linq To Sql

发布于 2024-12-21 15:26:38 字数 608 浏览 4 评论 0原文

我使用的是 EF Code First 4.2, 当需要动态构建 where 子句时,您提出什么样的解决方案? 然而,包含功能是非常需要的:

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子句必须是动态的!

I am using EF Code first 4.2,
What sort of solution do you propose when the where clause needs to be dynamically built?
Yet Include functionality would be highly required:

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

The dynamic condition above needs to lookup to another table to filter the records:
If I wanted to write that in Linq expression it would be something like:

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");

I basically needs the dynamic linq of the above expression, since for different types the Where clause fields changes (Contact is only an example), for example in one Model the FK field may be "AccountId" and in another it needs to be "AccountFKId". So the Where clause has to be dynamic!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怪我鬧 2024-12-28 15:26:38

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

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

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

// Other wheres

Linq 是强类型的,因此您始终至少必须知道要在 Set<>调用。您可以使其通用但不是动态的(除非您要通过反射完整地编写它)。

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

IQueryable is composable so you can build query on the fly:

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

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

// Other wheres

Linq is strongly typed so you always at least have to know what type are you going to start with in your Set<> call. You can make it generic but not dynamic (unless you are going to write it whole through reflection).

You can use dynamic linq to define where conditions with strings but again you will at least have to know type for Set<>.

习ぎ惯性依靠 2024-12-28 15:26:38

更新

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

使用 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 子句。

UPDATE

I was able to solve the issue with directly modifying the expression tree.

Using an idea from TomasP's blog helped a lot:

The key was to create a second IQueryable for the internal query and then pass it as an expression to the existing dynamic model's IQueryable expression.

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);

Now you can pass the anyMethodExpr to the original Entity's IQueryable where clause.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文