28

代码:

double cafeSales = db.InvoiceLines
    .Where(x =>
        x.UserId == user.UserId &&
        x.DateCharged >= dateStart &&
        x.DateCharged <= dateEnd)
    .Sum(x => x.Quantity * x.Price);

错误:

转换为值类型“Double”失败,因为具体化值为 null。结果类型的泛型参数或查询必须使用可为空的类型。

我已经看到的:

转换为值类型“Int32”失败,因为具体化值为 null

转换为值类型“十进制”失败,因为具体化值为 null

我尝试过的:

double cafeSales = db.InvoiceLines
    .Where(x =>
        x.UserId == user.UserId &&
        x.DateCharged >= dateStart &&
        x.DateCharged <= dateEnd)
    .DefaultIfEmpty()
    .Sum(x => x.Quantity * x.Price);

和:

double? cafeSales = db.InvoiceLines
    .Where(x =>
        x.UserId == user.UserId &&
        x.DateCharged >= dateStart &&
        x.DateCharged <= dateEnd)
    .Sum(x => x.Quantity * x.Price);

这些都不起作用。我知道问题的原因是该表中没有我传入的 UserId 的行。在这种情况下,我宁愿 Sum() 只返回一个 0 给我。有任何想法吗?

4

8 回答 8

70

最佳解决方案

double cafeSales = db.InvoiceLines
                     .Where(x =>
                                x.UserId == user.UserId &&
                                x.DateCharged >= dateStart &&
                                x.DateCharged <= dateEnd)
                     .Sum(x => (double?)(x.Quantity * x.Price)) ?? 0;
于 2013-10-22T06:26:20.707 回答
8

You can check if the collection has any correct results.

double? cafeSales = null;
var invoices = db.InvoiceLines
    .Where(x =>
        x.UserId == user.UserId &&
        x.DateCharged >= dateStart &&
        x.DateCharged <= dateEnd
    )
    .Where(x => x.Quantity != null && x.Price != null);
if (invoices.Any()) {
    cafeSales = invoices.Sum(x => x.Quantity * x.Price);
}
于 2013-03-08T15:54:44.143 回答
4

我知道这有点旧,但以防万一它对任何人都有帮助。

@Matt 我想该DefaultIFEmpty()方法应该适合您,以防万一您为要应用的列传递默认值Sum。此方法有一些您可能想要检查的重载,如果重载不支持您的要求,我建议进行类型转换。

 (query).DefaultIfEmpty(0) 
于 2013-07-23T07:46:13.650 回答
3

Quantity这应该可以解决问题(如果任一或Price不可为空,您可能必须删除其中一个条件):

var cafeSales = db.InvoiceLines
    .Where(x =>
        x.UserId == user.UserId &&
        x.DateCharged >= dateStart &&
        x.DateCharged <= dateEnd &&
        x.Quantity != null &&
        x.Price != null);

double cafeSalesTotal = 0;

if (cafeSales.Any())
{
    cafeSalesTotal = cafeSales.Sum(x => x.Quantity * x.Price);
}
于 2013-03-08T15:59:17.723 回答
1
join sim in ctx.EF.Collaterals on new { id = ini.cam.id, Type = 0 } equals new 
{ id = sim.CampaignId == null ? new Guid() : sim.CampaignId, sim.Type } 
into tempcoll
from sim in tempcoll.DefaultIfEmpty()

此解决方案有效。实际上,您需要使用三元运算符检查值并在第二列和第二个表中插入 Guid 如果为 null。它会起作用。“转换为值类型'Double'失败,因为物化值为空”将得到解决谢谢

于 2016-02-11T07:06:05.080 回答
0
 var cafeSales = db.InvoiceLines
.Where(x =>
    x.UserId == user.UserId &&
    x.DateCharged >= dateStart &&
    x.DateCharged <= dateEnd)
.Sum(x => x.Quantity * x.Price);

double i;
if(cafeSales==null) ? i=0 : i=(double)cafeSales.First();
于 2013-03-08T15:56:14.530 回答
0

上面的解决方案对我不起作用。我的问题是相似的。我确信没有返回任何行,但 Sum 的行为有些奇怪。所以我决定在调用 lambda 表达式之前添加一个检查,在这里我检查 lambda 返回的行的计数属性。如果它大于零,那么我调用 sum 表达式。这对我有用。

于 2015-06-11T08:47:34.097 回答
0

.NET 4.0,Nullable 有一个“GetValueOrDefault()”方法。因此,如果您将查询转换为 Nullable,那么您可以在完成时得到正确的类型。此方法还将生成正确的单个 SQL SELECT SUM 查询,并且比其他通过 linq 将整个记录集返回到以后求和的解决方案更快

decimal result = ((decimal?)query.Where(w => w.Customer =="ABC").Sum(s =>  (decimal?)s.Amount)).GetValueOrDefault();
于 2020-02-23T16:32:52.463 回答