sql 使用 left join group by 和 sum() 抛出异常的 LINQ
sql to LINQ with left join group by and sum() throws exception
我有一个已转换为 LINQ 表达式的查询。但是抛出 Null 异常。
Objective:支付类型可以有三个值(0、1、2)。我需要查询所有三种支付类型的所有货币的总金额。此外,如果对于 paymentType 的三个值中的任何一个,特定货币的记录都不存在。金额应显示为零。
Table结构:
Currency varchar(10),
PaymentType(int),
amount(decimal)
查询:
select aa.Currency,aa.PaymentType,sum(bb.amount) from (
select * from (select distinct paymenttype from payment) a cross join
(select distinct currency from payment) c
) aa left join payment bb on aa.PaymentType = bb.PaymentType and
aa.Currency = bb.Currency group by aa.PaymentType,aa.Currency
order by aa.Currency
Linq 表达式:
var temp = _db.Payments.Select(c => c.PaymentType) .Distinct()
.SelectMany(c => _db.Payments.Select(a => a.Currency).Distinct(),
(PaymentType, Currency) => new { PaymentType, Currency }).ToList();
var data = from p in temp join c in _db.Payments on new {
p.PaymentType, p.Currency } equals new { c.PaymentType, c.Currency }
into j1 from j2 in j1.DefaultIfEmpty() group j2 by new {
p.PaymentType, p.Currency } into grouped select new { paymenttype =
grouped.Key.PaymentType, currency = grouped.Key.Currency, amount =
grouped.Sum(t => (decimal?)t.Amount ?? 0) };
但是由于声明新时 SelectMany 语句中的 NULL 异常,它给我 "Object Reference" 错误。
t => (decimal?)t.Amount ?? 0
有人可以帮助我哪里做错了。
我用一些示例数据重写了代码并重现了所描述的错误。
var Payments = new [] {new {PaymentType = 0, Currency = "EUR", Amount = 10},
new {PaymentType = 0, Currency = "CHF", Amount = 70},
new {PaymentType = 2, Currency = "CHF", Amount = 80},
new {PaymentType = 1, Currency = "GBP", Amount = 90},
new {PaymentType = 1, Currency = "EUR", Amount = 100}};
var temp = Payments.Select(c => c.PaymentType).Distinct()
.SelectMany(c => Payments.Select(a => a.Currency).Distinct(),
(pt, cur) => new { PaymentType = pt, Currency = cur })
.ToList();
var data = from p in temp
join c in Payments on new { p.PaymentType, p.Currency } equals new { c.PaymentType, c.Currency } into j1
from j2 in j1.DefaultIfEmpty()
group j2 by new
{
p.PaymentType,
p.Currency
} into grouped
select grouped;
foreach (var g in data.ToList())
{
Console.WriteLine("{0},{1},{2}", g.Key.PaymentType, g.Key.Currency, g.Sum(t => t.Amount));
}
Console.ReadLine();
所以问题是 t.amount 不为空:t 本身为空。所以你需要调整的是:
grouped.Sum(t => t == null ? 0 : t.Amount)
我有一个已转换为 LINQ 表达式的查询。但是抛出 Null 异常。
Objective:支付类型可以有三个值(0、1、2)。我需要查询所有三种支付类型的所有货币的总金额。此外,如果对于 paymentType 的三个值中的任何一个,特定货币的记录都不存在。金额应显示为零。
Table结构:
Currency varchar(10),
PaymentType(int),
amount(decimal)
查询:
select aa.Currency,aa.PaymentType,sum(bb.amount) from (
select * from (select distinct paymenttype from payment) a cross join
(select distinct currency from payment) c
) aa left join payment bb on aa.PaymentType = bb.PaymentType and
aa.Currency = bb.Currency group by aa.PaymentType,aa.Currency
order by aa.Currency
Linq 表达式:
var temp = _db.Payments.Select(c => c.PaymentType) .Distinct()
.SelectMany(c => _db.Payments.Select(a => a.Currency).Distinct(),
(PaymentType, Currency) => new { PaymentType, Currency }).ToList();
var data = from p in temp join c in _db.Payments on new {
p.PaymentType, p.Currency } equals new { c.PaymentType, c.Currency }
into j1 from j2 in j1.DefaultIfEmpty() group j2 by new {
p.PaymentType, p.Currency } into grouped select new { paymenttype =
grouped.Key.PaymentType, currency = grouped.Key.Currency, amount =
grouped.Sum(t => (decimal?)t.Amount ?? 0) };
但是由于声明新时 SelectMany 语句中的 NULL 异常,它给我 "Object Reference" 错误。
t => (decimal?)t.Amount ?? 0
有人可以帮助我哪里做错了。
我用一些示例数据重写了代码并重现了所描述的错误。
var Payments = new [] {new {PaymentType = 0, Currency = "EUR", Amount = 10},
new {PaymentType = 0, Currency = "CHF", Amount = 70},
new {PaymentType = 2, Currency = "CHF", Amount = 80},
new {PaymentType = 1, Currency = "GBP", Amount = 90},
new {PaymentType = 1, Currency = "EUR", Amount = 100}};
var temp = Payments.Select(c => c.PaymentType).Distinct()
.SelectMany(c => Payments.Select(a => a.Currency).Distinct(),
(pt, cur) => new { PaymentType = pt, Currency = cur })
.ToList();
var data = from p in temp
join c in Payments on new { p.PaymentType, p.Currency } equals new { c.PaymentType, c.Currency } into j1
from j2 in j1.DefaultIfEmpty()
group j2 by new
{
p.PaymentType,
p.Currency
} into grouped
select grouped;
foreach (var g in data.ToList())
{
Console.WriteLine("{0},{1},{2}", g.Key.PaymentType, g.Key.Currency, g.Sum(t => t.Amount));
}
Console.ReadLine();
所以问题是 t.amount 不为空:t 本身为空。所以你需要调整的是:
grouped.Sum(t => t == null ? 0 : t.Amount)