【问题标题】:How to reuse where clause in EF如何在 EF 中重用 where 子句
【发布时间】:2019-01-29 12:33:15
【问题描述】:

我想使用EF 进行查询,我的查询如下所示

var users = MyDbc.AspNetUsers.Where
            (
                  d => 
                  (
                      d.UserPlans.Where(m => m.IsActive == 1).FirstOrDefault().PlanId == 2
                      ||
                      (d.UserPlans.Where(m => m.IsActive == 1).FirstOrDefault().PlanId == 3 
                        && d.UserGroups.FirstOrDefault().Group.AdminId == d.Id)
                  )
            );

如何避免两次查询用户计划? 在SQL 我会写以下内容

SELECT * FROM AspNetUsers U INNER JOIN UserPlan UP ON U.Id = UP.UserId 
WHERE UP.IsActive = 1
AND (
PlanId=2 OR (PlanId=3 AND EXISTS(SELECT 1 FROM [Group] WHERE AdminId=U.Id ))
)

【问题讨论】:

  • 整个 Linq 查询将被转换为一个 SQL 查询,因此您实际上并没有查询 UserPlans 两次。
  • 您可以使用((System.Data.Entity.Core.Objects.ObjectQuery)query).ToTraceString()轻松检查生成的 SQL 查询
  • 我使用分析器检查查询,似乎我有两个outer apply statements of UserPlans

标签: c# linq entity-framework-6


【解决方案1】:

只需使用内置查询语法:

var users = from user in MyDbc.AspNetUsers
            from plan in user.UserPlans.Where(m=>m.IsActive == 1)
            where plan.PlanId == 2 || plan.PlanId == 3 && ...

在选择查询时间变量方面更加灵活。当您的查询变大时,它更具可读性。对于简单的查询,我个人仍然使用纯 LINQ 扩展。

附言

正如评论中提到的@juharr,你的查询可能会被SQL提供者优化,所以你的性能很好,但是你的查询的可读性和抗故障能力确实很差。

【讨论】:

    【解决方案2】:

    我可能会将其打包到视图或存储过程中(如果您需要动态 ID)并单独加载。

    CREATE VIEW Users
    AS   
    SELECT * FROM AspNetUsers U INNER JOIN UserPlan UP ON U.Id = UP.UserId 
    WHERE UP.IsActive = 1
    AND (
    PlanId=2 OR (PlanId=3 AND EXISTS(SELECT 1 FROM [Group] WHERE AdminId=U.Id ))
    )
    GO  
    

    然后在c#中调用它...

    var users = MyDbc.Users.ToList();
    

    ……就这样。

    【讨论】:

      【解决方案3】:

      我认为您正在寻找这个。您可以直接在第一个 where 中进行两项检查。

      d.UserPlans.Where(m => m.IsActive == 1 && 
      (m.PlanId == 2 || (m.PlandId == 3 &&
      d.UserGroups.FirstOrDefault().Group.AdminId == d.I)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-06
        • 2012-06-08
        • 1970-01-01
        相关资源
        最近更新 更多