【问题标题】:Automatically add some Where clauses to a Linq Expression Tree自动将一些 Where 子句添加到 Linq 表达式树
【发布时间】: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 之后,但我宁愿不要从数据库中提取比我需要的更多的东西。

感谢您的任何提示!

【问题讨论】:

    标签: c# linq entity-framework


    【解决方案1】:

    是的。

    您可以通过在 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。

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

    编辑:

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

    【讨论】:

      【解决方案2】:

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

      此页面详细说明了如何执行此操作,并详细说明了我认为您正在寻找的内容。

      http://www.crazysalsadancer.com/2008/08/efficient-data-loading-with-linq-using.html

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 2018-01-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-15
          • 2011-10-03
          相关资源
          最近更新 更多