通过使用.NET 7,我的代码如下
var query = from c in dbContext.Customers
from o in dbContext.Orders.Select(o => new { Id = o.Id, Number = o.Number }).Where(o => o.CustomerId == c.Id)
.DefaultIfEmpty()
select new
{
Customer = c,
Order = o
};
var result = await query.ToListAsync();
我在 Orders.Select 语句中使用匿名类型的原因是我只想获取 2 个字段订单 ID 和订单号以加快性能,
有些客户不会有任何订单,所以在运行时,它会抛出异常 Nullable object must have a value with stack trace :
System.InvalidOperationException HResult=0x80131509
Message=Nullable 对象必须有一个值。
Source=System.Private.CoreLib StackTrace: 在 System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_NoValue() 在 Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
你能告诉我应该改变什么来摆脱这个异常吗,谢谢你的帮助。
尝试通过以下方式检查 null,但 不起作用
dbContext.Orders.Select(o => o != null ? new { Id = o.Id, Number = o.Number } : new { Id = Guid.NewGuid(), Number = 0})
dbContext.Orders.Select(o => o != null ? new Order { Id = o.Id, Number = o.Number } : (Order) null)
select new { Customer = c, Order = o != null ? o : new Order() { Id = Guid.NewGuid(), Number = 0}}
你在 LINQ 查询中使用了 DefaultIfEmpty() 方法,它返回一个空值在这种情况下,当没有找到客户的匹配订单时,它会通过错误。 为了避免这个问题试试这个,
var query = from c in dbContext.Customers
from o in dbContext.Orders
.Where(o => o.CustomerId == c.Id)
.Select(o => new { Id = o.Id, Number = o.Number })
.DefaultIfEmpty()
select new
{
Customer = c,
Order = o?.Id != null ? new { Id = o.Id, Number = o.Number } : null
};
var result = await query.ToListAsync();
我会重写查询以在最终投影中执行投影:
var query = from c in dbContext.Customers
from o in dbContext.Orders
.Where(o => o.CustomerId == c.Id)
.DefaultIfEmpty()
select new
{
Customer = c,
Order = o == null
? null
: new
{
o.Id,
o.Number
}
};
但是您也可以尝试显式指定匿名成员的类型:
var query = from c in dbContext.Customers
from o in dbContext.Orders
.Select(o => new { Id = (int?)o.Id, Number = o.Number })
.Where(o => o.CustomerId == c.Id)
.DefaultIfEmpty()
select new
{
Customer = c,
Order = o
};
请注意,您始终可以正确设置关系并执行以下操作,而不是手动编写连接:
var list = ctx.Customers
.Select(c => new
{
Customer = c,
Orders = c.Orders.Select(o => new { o.Id, ... }).ToList()
})
.ToList();
var query = from c in dbContext.Customers
join a in dbContext.Orders on c.CustomerId equals a.CustomerId into ps
from suborder in ps.DefaultIfEmpty()
select new
{
Customer = c,
Order = suborder //deal with null, assign some generic object or whatever you need
};
var result = await query.ToListAsync();
Console.WriteLine(result);
我想这就是你要找的。请更改您的财产名称