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