【问题标题】:Linq to entity adding Where() clause breaks queryLinq to entity 添加 Where() 子句会中断查询
【发布时间】:2019-02-08 16:44:26
【问题描述】:

使用 Microsoft SQL Entity Framework,我有一个查询,有时我有一个过滤条件,有时我没有,所以我尝试执行下面显示的操作。如果条件不为空,则不是按预期进行查询,而是从Org_Hierarchy 表中查询所有内容,然后从Workers 表中查询所有内容,然后因为耗时太长而死:

void SomeMethod(Func<PRT, bool> whereClause) {
    IQueryable<PRT> query;
    if (whereClause != null) {
        query = PRT.Where(whereClause).AsQueryable();
    } else {
        query = PRT.AsQueryable();
    }

    var data = from prt in query
               // LEFT OUTER JOIN Worker a ON prt.assigned_to = a.WWID
           join a_join in Worker on prt.assigned_to equals a_join.WWID into a_grp
           from a in a_grp.DefaultIfEmpty()
               // LEFT OUTER JOIN Worker c ON prt.closed_by = c.WWID
           join c_join in Worker on prt.closed_by equals c_join.WWID into c_grp
           from c in c_grp.DefaultIfEmpty()
               // LEFT OUTER JOIN Worker r ON prt.requestor = r.WWID
           join r_join in Worker on prt.requestor equals r_join.WWID into r_grp
           from r in r_grp.DefaultIfEmpty()
               // LEFT OUTER JOIN Org_Hierarchy o ON prt.org3 = o.OrganizationHierarchyUnitCd AND o.OrganizationHierarchyUnitTreeLevelNbr = 3 AND o.Active = true
           join o in Org_Hierarchy on prt.org3 equals o.OrganizationHierarchyUnitCd
           select new PrtInput {

如果我更改查询并将某些内容直接放入其中,仅用于测试,例如显示的最后一行上方的where prt.id == Guid.NewGuid(),则查询会在一秒钟内返回。能够在查询中动态添加 where 子句的技巧是什么?

上面的代码来自 LinqPAD,这就是为什么正常的“上下文”东西都不见了的原因。

【问题讨论】:

    标签: linq-to-sql linq-to-entities


    【解决方案1】:

    我不确定,但我认为你应该使用这样的东西:

    Expression<Func<PRT ,bool>> whereClause
    

    安装于:

    Func<PRT ,bool> whereClause
    

    使用 Func 时,首先从 db 获取数据到内存然后过滤内存中的数据,但如果使用 Epression 过滤器发送到 sql 并返回结果。

    为了获得更好的性能,您可以像这样使用 AsNoTracking():

    if (whereClause != null) {
        query = PRT.Where(whereClause).AsQueryable().AsNoTracking();
    } else {
        query = PRT.AsQueryable().AsNoTracking();
    } 
    

    当您只想在您的数据库上运行查询而不对结果进行任何插入、更新或删除时,最好使用 AsNoTracking。

    我希望这能回答你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多