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

时间:2011-07-28 19:05:24

标签: c# .net entity-framework linq-to-entities

我有以下代码。我收到了错误:

  

“转换为值类型'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();

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

8 个答案:

答案 0 :(得分:315)

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;

这首先转换为int?告诉C#编译器该表达式确实可以返回null,即使Sum()返回int。然后我们使用普通??运算符来处理null情况。

基于这个答案,我写了一个blog post,其中包含LINQ to SQL和LINQ to Entities的详细信息。

答案 1 :(得分:8)

要允许可为空的Amount字段,只需使用空合并运算符将空值转换为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();

答案 2 :(得分:4)

您使用的aggregate函数没有让项目执行操作,您必须验证linq查询是否给出了如下结果:

var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0

答案 3 :(得分:4)

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

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

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

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

在查看刷新之前:

public int SubscriberId { get; set; }

查看刷新后:

public Nullable<int> SubscriberId { get; set; }

在EDMX中删除并添加视图。

希望它有所帮助。

答案 4 :(得分:2)

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

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
                            }

答案 5 :(得分:1)

我看到这个问题已经回答了。但是如果你想将它分成两个语句,可以考虑以下内容。

var credits = from u in context.User
              join ch in context.CreditHistory 
                  on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch;

var creditSum= credits.Sum(x => (int?)x.Amount) ?? 0;

答案 6 :(得分:0)

在运行时使用此代码在Entity Framework 6中出现此错误:

var fileEventsSum = db.ImportInformations.Sum(x => x.FileEvents)

来自LeandroSoares的更新:

将其用于单次执行:

var fileEventsSum = db.ImportInformations.Sum(x => (int?)x.FileEvents) ?? 0

<强>原始

更改为此然后工作:

var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;

答案 7 :(得分:0)

我也面临着同样的问题,并通过使用“?”将列设置为可空值来解决。运算符。

Sequnce = db.mstquestionbanks.Where(x => x.IsDeleted == false && x.OrignalFormID == OriginalFormIDint).Select(x=><b>(int?)x.Sequence</b>).Max().ToString();

有时返回null。