如何重用EF中的where子句

时间:2019-01-29 12:33:16

标签: c# linq entity-framework-6

我想使用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)
                  )
            );

如何避免两次查询UserPlan? 在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 ))
)

3 个答案:

答案 0 :(得分:4)

只需使用内置查询语法:

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扩展。

PS

正如注释中提到的 @juharr 一样,您的查询可能会通过SQL提供程序进行优化,因此您的性能不错,但是查询的可读性和抗错性确实很差。

答案 1 :(得分:1)

我可能会将其打包到视图或存储过程中(如果需要动态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();

...那样。

答案 2 :(得分:1)

我认为您正在寻找这个。您只需在第一个位置直接进行两项检查即可。

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