CODE:
double cafeSales = db.InvoiceLines
.Where(x =>
x.UserId == user.UserId &&
x.DateCharged >= dateStart &&
x.DateCharged <= dateEnd)
.Sum(x => x.Quantity * x.Price);
错误:
转换为值类型'Double'失败,因为具体化值为null。结果类型的泛型参数或查询必须使用可空类型。
我已经看到了什么:
The cast to value type 'Int32' failed because the materialized value is null
The cast to value type 'Decimal' failed because the materialized value is 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给我。有什么想法吗?
答案 0 :(得分:58)
最佳解决方案
double cafeSales = db.InvoiceLines
.Where(x =>
x.UserId == user.UserId &&
x.DateCharged >= dateStart &&
x.DateCharged <= dateEnd)
.Sum(x => (double?)(x.Quantity * x.Price)) ?? 0;
答案 1 :(得分:8)
您可以检查集合是否有正确的结果。
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);
}
答案 2 :(得分:4)
我知道这有点旧,但万一它可以帮助任何人。
@Matt我想DefaultIFEmpty()
方法应该适用于您,以防您为要应用Sum
的列传递默认值。这个方法有一些你可能需要检查的重载,如果重载不支持你的要求,我建议使用类型转换。
(query).DefaultIfEmpty(0)
答案 3 :(得分: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);
}
答案 4 :(得分: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();
答案 5 :(得分:0)
上述解决方案对我没有用。我的问题很相似。我确信没有返回任何行,但Sum表现得很奇怪。所以我决定在调用lambda表达式之前添加一个检查,其中我检查lambda返回的行的count属性。如果它大于零,那么我调用sum表达式。这对我有用。
答案 6 :(得分:0)
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'失败,因为物化值为null”将被解决 感谢
答案 7 :(得分:0)
.NET 4.0,Nullable具有“ GetValueOrDefault()”方法。 因此,如果将查询强制转换为Nullable,则完成后可以得到正确的Type。 此方法还将生成正确的单个SQL SELECT SUM查询,并且比通过linq将整个记录集返回到更高的总和的其他解决方案要快。
decimal result = ((decimal?)query.Where(w => w.Customer =="ABC").Sum(s => (decimal?)s.Amount)).GetValueOrDefault();