ошибка в запросе Linq - PullRequest
       6

ошибка в запросе Linq

1 голос
/ 03 апреля 2011

У меня есть следующие Linq:

var ownerRegistryId = 731752693037116688;
var excludeTypes = new[]
{
    "CA00", "CA01", "CA03", "CA04", "CA02",
    "PA00", "PA01", "PA02", "PA03", "PA04"
};

var maxStateChangeMonth = 4;
var excludeStatusId = 999;
var includeMortgage = new[] { "CL10", "CL11", "PL10", "PL11" };

 var sum = (
    from account in context.Accounts
    from owner in account.AccountOwners
    where owner.AccountOwnerRegistryId == ownerRegistryId
    where !excludeTypes.Contains(account.AccountType)
    where account.StateChangeDate == null ||
        (account.StateChangeDate.Month - DateTime.Now.Month)
            <= maxStateChangeMonth
    where includeMortgage.Contains(account.AccountType) ||
            account.AccountType.Contains("Mortgage")
    where account.AccountStatusId != excludeStatusId
    select account.MinimumInstallment)
    .Sum(minimumInstallment => Math.Abs(minimumInstallment));

, но я получаю ошибку:

Ошибка приведения к типу значения 'Десятичное', поскольку материализованное значение равно нулю.Либо универсальный параметр типа результата, либо запрос должен использовать обнуляемый тип.

эта ошибка появляется, как только я добавляю следующее:

where (includeMortgage.Contains(account.AccountType) ||
    account.AccountType.Contains("Mortgage"))

Если я удалю это из запроса выше, это работает.

Запрос является переводом следующего SQL:

    SELECT Sum(ABS([Minimum Installment])) AS SumOfMonthlyPayments FROM tblAccount 
    INNER JOIN tblAccountOwner ON tblAccount.[Creditor Registry ID] = tblAccountOwner.
    [Creditor Registry ID] AND tblAccount.[Account No] = tblAccountOwner.[Account No] 
    WHERE (tblAccountOwner.[Account Owner Registry ID] = 731752693037116688)
     AND (tblAccount.[Account Type] NOT IN 
    ('CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04'))
    AND (DATEDIFF(mm, tblAccount.[State Change Date], GETDATE()) <= 
   4 OR tblAccount.[State Change Date] IS NULL AND ((tblAccount.[Account Type] IN ('CL10','CL11','PL10','PL11')) OR
    tblAccount.[Account Type] LIKE 'Mortgage')) AND (tblAccount.[Account Status ID] <> 999)

Ответы [ 2 ]

2 голосов
/ 03 апреля 2011

Я бы попробовал переписать последние две строки вашего запроса следующим образом:

var sum = (
...
select account)
.Sum(a => Math.Abs(a.MinimumInstallment));

Вот как я интерпретирую эту часть исключения "...or the query must use a nullable type".Используя проекцию select account.MinimumInstallment, вы получаете необнуляемый тип, а именно decimal, который является типом account.MinimumInstallment.

Не уверен, хотя, просто предположение.

Редактировать

Возможно, проблема в окончательном назначении var sum = ....Поскольку вы не указали тип результата явно, компилятор здесь выведет тип на decimal, потому что MinimumInstallment является десятичным.На самом деле запрос может вернуть null, когда выбранный набор записей был пуст, поэтому приведение к десятичному типу невозможно.

Итак, давайте поможем компилятору вывести тип результата запроса на decimal?:

var sum = (decimal?)(from ... ) ?? 0;

(замените from ... на ваш исходный запрос или, возможно, на мою модифицированную версию выше.)

Edit 2

OK, первое Edit didnне работает (согласно комментарию в другом вопросе).Действительно, я мог бы воспроизвести проблему в похожем примере.Но в моем примере сработало следующее:

var sum = (
    ...
    select account)
    .Sum(a => (decimal?)Math.Abs(a.MinimumInstallment))
    .GetDefaultOrValue();
0 голосов
/ 03 апреля 2011

Попробуйте использовать:
Math.Abs ​​((десятичное число) (минимальная установка. Значение значения: минимальная установка: 0));

Как насчет:

 Math.Abs((decimal)(minimumInstallment!= null ? minimumInstallment : 0));  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...