自动将一些 Where 子句添加到 Linq 表达式树
Posted
技术标签:
【中文标题】自动将一些 Where 子句添加到 Linq 表达式树【英文标题】:Automatically add some Where clauses to a Linq Expression Tree 【发布时间】:2010-09-18 01:10:25 【问题描述】:我正在使用实体框架和 Linq to Entities。我创建了一个小型数据库模式和框架来实现版本控制和本地化。现在每个实体都包含两个或三个表(即 Product、ProductBase 和 ProductLocal)。
我的 linq 总是包含以下样板代码:
from o in DB.Product
from b in o.Base
from l in o.Local
WHERE o.VersionStatus == (int)VersionStatus.Active
&& b.VersionStatus == (int)VersionStatus.Active
&& l.VersionStatus == (int)VersionStatus.Active
&& l.VersionLanguage == Context.CurrentLanguage
select new ProductInstance Instance = o, Base = b, Local = l
我想要完成的是把上面的变成:
(from o in DB.Product
from b in o.Base
from l in o.Local
select new ProductInstance Instance = o, Base = b, Local = l ).IsActive()
或者最坏的情况是:
from o in DB.Product.Active()
from b in o.Base.Active()
from l in o.Local.Active()
select new ProductInstance Instance = o, Base = b, Local = l
我已经扩展了 EDM 生成的基类,以实现一些强制执行属性的接口( IVersionStatus 和/或 IVersionLanguage )。有什么方法可以遍历表达式树,检查表达式中的类型是否实现了该接口,然后相应地设置 VersionStatus?
我希望它像第一个选项一样简单,只是少写和/或忘记。我已经看到了事后的例子,在它的 IEnumerable 之后,但我宁愿不要从数据库中提取比我需要的更多的东西。
感谢您的任何提示!
【问题讨论】:
【参考方案1】:是的。
您可以通过在 IQueryable 上定义一个名为 IsActive 的扩展方法来做到这一点。 IQueryable 上有一个名为“Expression”的属性,它返回一个表达式树,表示从您的查询生成的 LINQ 方法调用链。
在你的情况下,看起来像这样:
DB.Product.SelectMany(o=>o.base, (o, b)=>newo.b).SelectMany(item=>o.local, (item, local)=>new item.o, item.b, item.local).Select(item=>new ProductInstance Instance = item.o, Base = item.b, Local=item.Local);
“DB.Product”是第一个 From 子句中的项目。每个剩余的“SelectMany”调用都是一个附加的 from 子句。
然后您可以深入研究表达式树以收集所有 from 子句元素。查看它们的类型,最后为 where 子句生成表达式树。
然后,您的扩展方法将使用您生成的 where 子句从 IQueryable 参数中返回 .Where。
当您尝试“foreach”结果时,生成的 Where 子句将在服务器上与其余查询一起执行。
编辑:
请注意,如果您希望它与显式的“Join”子句一起使用,那么除了“SelectMany”之外,您还需要添加对“Join”方法的支持。
【讨论】:
【参考方案2】:您需要使用 DataLoadOptions 类,以便它自动加载您在该对象上指定的外键关系。这将使它自动获取您指定的链接表,这正是您正在做的事情。
此页面详细说明了如何执行此操作,并详细说明了我认为您正在寻找的内容。
http://www.crazysalsadancer.com/2008/08/efficient-data-loading-with-linq-using.html
【讨论】:
【参考方案3】:我可能错了,但我认为 DataLoadOptions
不适用于实体框架。
【讨论】:
以上是关于自动将一些 Where 子句添加到 Linq 表达式树的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法可以将包含LINQ where子句的字符串添加到列表中?