Linq Count () всегда будет возвращать 1 в Visual Studio - PullRequest
0 голосов
/ 11 октября 2018

Фон

Сейчас у меня есть система с именем FoorBar, в которой есть пользователи, комнаты и полномочия.

Подробный фон

Пользователь может иметь много полномочий, и к одной авторизации может быть добавлено много комнат.Для этого у меня есть следующие таблицы: FooBar_User, FooBar_UserAuth, FooBar_Authorization, FoorBar_AuthType, FooBar_RoomAuth и Room_Inventory.

Мне нужен запрос для возврата идентификатора авторизации,количество комнат, которые есть у пользователя, тип авторизации и дата истечения срока авторизации.

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 Query

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 Output

AuthId  RmCnt   AuthType    ExpirationDate
30      0       Type1       12/31/2020
31      0       Type2       12/31/2020

Проблема

Проблема в том, что этот запрос LINQ отлично работает, когда он выполняется как в Linqer, так и в LINQPad.Вывод точно такой, как хотелось бы.Однако, когда он запускается в C # с ASP.NET, MVC и Entity Framework, RmCnt никогда не будет 0.Вместо этого это будет 1.Неважно, что изменилось, похоже, это так.Еще один пользователь задал аналогичный вопрос , но я не могу понять, как применить их решение с моим запросом.

Любая помощь будет признательна.

1 Ответ

0 голосов
/ 11 октября 2018

Я выяснил проблему

Проблема

Я до сих пор не уверен, что основная причина проблемы, поскольку LINQ Query, в котором я изначально отлично работалLINQPad и Linqer, но не в самом коде.

Однако одна из вещей, которые я изменил по сравнению с исходным выводом 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...