c# - Linq Count() 将始终在 Visual Studio 中返回 1
问题描述
背景
现在我有一个名为 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
问题
问题是这个 LINQ 查询在 Linqer 和 LINQPad 中运行时都能完美运行。输出完全符合要求。但是,当它在带有 ASP.NET、MVC 和实体框架的 C# 中运行时,RmCnt 永远不会是0
. 相反,它将是1
. 无论发生什么变化,似乎都是如此。另一位用户提出了类似的问题,但我不知道如何将他们的解决方案应用于我的查询。
任何帮助,将不胜感激。
解决方案
我解决了这个问题
问题
我仍然不确定问题的根本原因是什么,因为我最初在 LINQPad 和 Linqer 中完美运行的 LINQ 查询,但在实际代码中却没有。
但是,我从 Linqer 的原始输出中更改的一件事是更改p.ra.AuthTypeId != null
为,p.ra.AuthTypeId != 0
因为 Visual Studio 抱怨AuthTypeId
永远不能为空,因为它是一个int
而不是一个Nullable<int>
.
解决方案
这实际上是一个相当简单的改变。p.ra.AuthTypeId != 0
需要更改为p.ra != null
. 此解决方案使 Visual Studio 不会抱怨可空类型,但仍保持相同的输出。
完整的工作 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 != null),
AuthType = g.Key.AuthTypeAbbr,
ExpirationDate = g.Key.ExpirationDate
}
推荐阅读
- jquery - 递归 Ajax 调用在 IE11 中不起作用
- c# - 在 IIS 服务器中部署 asp.net Web 应用程序时如何解决水晶报表问题
- android - Android 应用和展示位置
- java - MAC 中 ProcessBuilder 和 FFMPEG 的权限被拒绝
- java - 查询 SELECT 时出现 SQLiteException
- jupyter-notebook - 带有自定义单用户图像的 Jupyterhub 为“/home/jovyan/work”引发“没有这样的文件或目录”
- c++ - 编译器选择不使用 REP MOVSB 指令进行字节数组移动
- apache-spark - 如何根据列数据将数据与数据框中的行一起展平(或分解)?
- django - 具有非模型字段序列化的 AttributeError
- android - Android 上的 AWS Cognito - 如何从刷新令牌中获取新会话