背景
现在,我有一个名为FoorBar的系统,其中包含用户,房间和授权。
详细背景
用户可以具有多个授权,并且可以将多个房间添加到一个授权中。为了解决这个问题,我有下表:FooBar_User
,FooBar_UserAuth
,FooBar_Authorization
,FoorBar_AuthType
,FooBar_RoomAuth
和Room_Inventory
。
我需要查询以返回授权ID,用户拥有的房间数,授权类型以及授权的到期日期。
SQL
生成所需输出的SQL如下:
SELECT a.AuthId
,COUNT(ra.RoomAuthId) AS RmCnt
,fat.AuthTypeAbbr
,a.ExpirationDate
FROM FooBar_User AS u
INNER JOIN FooBar_UserAuth AS ua ON u.UserId = ua.UserId
INNER JOIN FooBar_Authorization AS a ON ua.AuthId = a.AuthId
INNER JOIN FooBar_AuthType AS fat ON a.AuthTypeId = fat.AuthTypeId
LEFT JOIN FooBar_RoomAuth AS ra ON a.AuthId = ra.AuthId AND ra.IsActive = 1
LEFT JOIN Room_Inventory AS ri ON ra.RmId = ri.RMID AND ri.IsActive = 1
WHERE a.IsActive = 1
AND u.IsActive = 1
AND u.UserId = 10
GROUP BY a.AuthId, fat.AuthTypeAbbr, a.ExpirationDate
LINQ查询
from ua in db.FooBar_UserAuth
join ra in db.FooBar_RoomAuth
on new { ua.FooBar_Authorization.AuthId, IsActive = true }
equals new { ra.AuthId, ra.IsActive } into raJoin
from ra in raJoin.DefaultIfEmpty()
join ri in db.Room_Inventory
on new { ra.RmId, IsActive = true }
equals new { RmId = ri.RMID, ri.IsActive } into riJoin
from ri in riJoin.DefaultIfEmpty()
where
ua.FooBar_Authorization.IsActive &&
ua.IsPi == true &&
ua.FooBar_User.IsActive &&
ua.FooBar_User.UserId == 10
group new { ua.FooBar_Authorization, ua.FooBar_Authorization.FooBar_AuthType, ra } by new
{
AuthId = (int?)ua.FooBar_Authorization.AuthId,
ua.FooBar_Authorization.FooBar_AuthType.AuthTypeAbbr,
ua.FooBar_Authorization.ExpirationDate
} into g
select new
{
AuthId = g.Key.AuthId.Value,
RmCnt = g.Count(p => p.ra.RoomAuthId != 0),
AuthType = g.Key.AuthTypeAbbr,
ExpirationDate = g.Key.ExpirationDate
}
LINQPad和Linqer输出
AuthId RmCnt AuthType ExpirationDate
30 0 Type1 12/31/2020
31 0 Type2 12/31/2020
问题
问题是,当在Linqer和LINQPad中运行该LINQ查询时,它可以完美运行。输出完全符合要求。但是,当它在带有ASP.NET,MVC和实体框架的C#中运行时,RmCnt将永远不会是0
。相反,它将是1
。无论发生什么变化,情况似乎都是如此。另一位用户问了similar question,但我不知道如何在查询中应用他们的解决方案。
任何帮助将不胜感激。
答案 0 :(得分:0)
我发现了问题
问题
我仍然不确定问题的根本原因是因为我本来可以在LINQPad和Linqer中完美运行的LINQ查询,但是在实际代码中却没有。
但是,我从Linqer的原始输出更改的一件事是将p.ra.AuthTypeId != null
更改为p.ra.AuthTypeId != 0
,因为Visual Studio抱怨AuthTypeId
永远不能为null,因为它是{ {1}},而不是int
。
解决方案
这实际上是一个相当简单的更改。 Nullable<int>
需要更改为p.ra.AuthTypeId != 0
。此解决方案使Visual Studio不会抱怨可为空的类型,但仍保持相同的输出。
完整的LINQ查询
p.ra != null