C# 自动向Linq表达式树添加一些Where子句

C# 自动向Linq表达式树添加一些Where子句,c#,linq,entity-framework,C#,Linq,Entity Framework,我正在使用实体框架和Linq转换实体。我创建了一个小型数据库模式和框架来实现版本控制和本地化。每个实体现在由两个或三个表组成(即Product、ProductBase和ProductLocal) My linq始终包含以下样板代码: from o in DB.Product from b in o.Base from l in o.Local WHERE o.VersionStatus == (int)VersionStatus.Active && b.VersionSt

我正在使用实体框架和Linq转换实体。我创建了一个小型数据库模式和框架来实现版本控制和本地化。每个实体现在由两个或三个表组成(即Product、ProductBase和ProductLocal)

My 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之后进行的,但是我宁愿不从数据库中提取比我需要的更多的数据


谢谢你的提示

您需要使用DataLoadOptions类,以便它自动加载您在该对象上指定的外键关系。这将使它能够自动获得您指定的链接表,而这正是您正在做的事情

这一页详细介绍了如何做到这一点,并告诉更多关于我认为你在寻找什么


我可能错了,但我认为
DataLoadOptions
不适用于实体框架。

是的

可以通过在IQueryable上定义名为IsActive的扩展方法来实现这一点。 IQueryable上有一个名为“Expression”的属性,它返回一个表达式树,表示从查询生成的LINQ方法调用链

在您的情况下,将显示如下内容:

DB.Product.SelectMany(o=>o.base, (o, b)=>new{o.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 off

当您尝试对结果进行“foreach”时,结果Where子句将与查询的其余部分一起在服务器上执行

编辑:

请注意,如果您希望使用显式的“Join”子句,那么除了“SelectMany”之外,还需要添加对“Join”方法的支持