转换为值类型"Int32"失败,因为实现值为null

zos*_*sim 190 .net c# linq-to-entities entity-framework

我有以下代码.我收到错误:

"转换为值类型'Int32'失败,因为具体化值为null.结果类型的泛型参数或查询必须使用可空类型."

当CreditHistory表没有记录时.

var creditsSum = (from u in context.User
                  join ch in context.CreditHistory on u.ID equals ch.UserID                                        
                  where u.ID == userID
                  select ch.Amount).Sum();
Run Code Online (Sandbox Code Playgroud)

如何修改查询以接受空值?

And*_*bel 320

linq-to-sql查询不是作为代码执行,而是转换为SQL.有时,这是一种"漏洞抽象",会产生意外行为.

一个这样的情况是空处理,其中在不同的地方可能存在意外的空值....DefaultIfEmpty(0).Sum(0)可以帮助这个(非常简单)的情况,其中可能没有元素和sql的SUM返回,null而c#期望0.

更通用的方法是使用在生成的SQL返回意外的null的风险时??将其转换为COALESCE:

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select (int?)ch.Amount).Sum() ?? 0;
Run Code Online (Sandbox Code Playgroud)

这首先强制int?告诉C#编译器这个表达式确实可以返回null,即使Sum()返回一个int.然后我们使用普通??运算符来处理这个null案例.

根据这个答案,我写了一篇博文,其中详细介绍了LINQ to SQL和LINQ to Entities.

  • 感谢Anders,使用DefaultIfEmpty(0).Sum()的解决方案对我来说很好.我也用(int?)尝试了第二个解决方案...... ?? 0 ...,但它抛出与以前相同的异常.. (3认同)
  • @recursive:你的例子是LINQ-to-Objects,而不是LINQ-to-SQL(或LINQ-to-Entities).他们的基础数据提供商使他们的行为不同. (2认同)

rec*_*ive 8

要允许可空Amount字段,只需使用null合并运算符将空值转换为0.

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch.Amount ?? 0).Sum();
Run Code Online (Sandbox Code Playgroud)


Moh*_*ori 6

我使用了这段代码并且它正确响应,只有输出值可以为空。

var packesCount = await botContext.Sales.Where(s => s.CustomerId == cust.CustomerId && s.Validated)
                                .SumAsync(s => (int?)s.PackesCount);
                            if(packesCount != null)
                            {
                                // your code
                            }
                            else
                            {
                                // your code
                            }
Run Code Online (Sandbox Code Playgroud)


小智 5

您正在使用的aggregate函数没有获取要执行操作的项目,您必须验证 linq 查询是否给出了一些结果,如下所示:

var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0
Run Code Online (Sandbox Code Playgroud)

  • 这将使 sdv 执行两次。这不是您想要的 IQueryables (12认同)

liv*_*ove 5

当我尝试从视图中进行选择时出现此错误消息。

问题是该视图最近获得了一些新的空行(在 SubscriberId 列中),并且尚未在 EDMX 中更新(首先是 EF 数据库)。

该列必须是 Nullable 类型才能工作。

var Dealer = Context.Dealers.Where(x => x.dealerCode == DealerCode).FirstOrDefault();

视图刷新前:

public int SubscriberId { get; set; }
Run Code Online (Sandbox Code Playgroud)

视图刷新后:

public Nullable<int> SubscriberId { get; set; }
Run Code Online (Sandbox Code Playgroud)

在 EDMX 中删除和添加视图有效。

希望它可以帮助某人。