Linq 查询错误
我有以下 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));
但出现错误:
转换为值类型“Decimal” 失败是因为物化值 为空。结果类型的 通用参数或查询必须 使用可为 null 的类型。
一旦我添加以下内容,就会出现此错误:
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)
I have following 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));
but I get the error:
The cast to value type 'Decimal'
failed because the materialized value
is null. Either the result type's
generic parameter or the query must
use a nullable type.
this error comes as soon as I add this:
where (includeMortgage.Contains(account.AccountType) ||
account.AccountType.Contains("Mortgage"))
If I remove this from above query, it works.
The query is translation of following 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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会尝试像这样重写查询的最后两行:
这就是我解释异常
“...或者查询必须使用可为空类型”
的这一部分的方式。通过使用投影select account.MinimumInstallment
,您将获得一个不可为 null 的类型,即decimal
,它是account.MinimumInstallment
的类型。但不确定,只是猜测。
编辑
问题实际上可能是最终赋值
var sum = ...
。由于您没有明确指定结果类型,编译器将在此处将类型推断为十进制,因为MinimumInstallment
是十进制。当所选记录集为空时,查询实际上可以返回null
,因此不可能转换为十进制。因此,让我们帮助编译器将查询的结果类型推断为
decimal?
:(将
from ...
替换为您的原始查询或我上面的修改版本。 )编辑 2
好的,第一个编辑不起作用(根据另一个问题中的评论)。事实上,我可以在类似的例子中重现这个问题。但以下内容在我的示例中有效:
I'd try to rewrite the last two lines of your query like so:
That's how I interprete this part of the exception
"...or the query must use a nullable type"
. By using the projectionselect account.MinimumInstallment
you have a non-nullable type, namelydecimal
which is the type ofaccount.MinimumInstallment
.Not sure though, just a guess.
Edit
The problem might actually be the final assignment
var sum = ...
. Since you don't specify the result type explicitely the compiler will here infer the type todecimal
becauseMinimumInstallment
is decimal. The query can actually returnnull
when the selected recordset was empty so the cast to decimal is impossible.So, let's help the compiler to infer the result type of the query to
decimal?
:(Replace
from ...
by your original query or maybe by my modified version above.)Edit 2
OK, the first Edit didn't work (according to comment in another question). Indeed I could reproduce the issue in a similar example. But the following worked in my example:
尝试使用:Math.Abs((decimal)(minimumInstallment.HasValue ? minimumInstallment : 0));
怎么样:
Try using:Math.Abs((decimal)(minimumInstallment.HasValue ? minimumInstallment : 0));
How about: