我正在编写一个查询来检索通知类型列表以及它们可以拥有的两种类型订阅者的单独计数。我是 EF Core 的新手,但我终于能够让它工作了。但是,我收到视觉工作室警告“取消引用可能为空的引用。”
当然,我可以使用#pragma warning禁用来抑制警告。但警告通常告诉我我做错了什么,所以我宁愿解决问题而不是隐藏它。然而,到目前为止我尝试过的事情只是将其从警告变成了错误。我没有主意,所以我想看看社区是否有。
下面是代码。底部附近的 s.SubscribedUserCount 是收到警告的行。
// code to get the two counts we need
var subscriptionQuery = _dbContext.Subscriptions
.Where(x => x.SiteEntityId == request.SiteGuid)
.GroupBy(x => x.NotificationTypeEntityId, (key, group) => new {
Id = key,
SubscribedUserCount = group.Count(p => p.SubscriberType == Domain.Enums.SubscriberType.User),
SubscribedRoleCount = group.Count(p => p.SubscriberType == Domain.Enums.SubscriberType.Role)
});
// now outer join to that code from NotificationTypes to get results we need
var results = await _dbContext.NotificationTypes
.GroupJoin(subscriptionQuery,
types => types.Id,
subs => subs.Id,
(types, subs) => new { types, subs })
.SelectMany(x => x.subs.DefaultIfEmpty(),
(t, s) => new GetNotificationTypesDto {
Id = t.types.Id,
Description = t.types.Description,
Name = t.types.Name,
WorkflowId = t.types.WorkflowId,
//#pragma warning disable CS8602 // Dereference of a possibly null reference.
SubscribedUserCount = s.SubscribedUserCount,
//#pragma warning restore CS8602 // Dereference of a possibly null reference.
SubscribedRoleCount = s.SubscribedRoleCount,
})
.ToListAsync(cancellationToken);
原来的代码其实是这样的:
SubscribedUserCount = s == null ? 0 : s.SubscribedUserCount,
SubscribedRoleCount = s == null ? 0 : s.SubscribedRoleCount,
因为我希望 SubscribedUserCount 和 SubscribedRoleCount 为 int 类型。这不会导致任何警告或语法错误,但它给了我一个运行时错误:“System.InvalidOperationException:Nullable 对象必须有一个值。” 我最终放弃了,将这些属性改为 nullable int,并使用我上面发布的代码:
SubscribedUserCount = s.SubscribedUserCount,
SubscribedRoleCount = s.SubscribedRoleCount,
认为这可以解决问题。确实如此,因为代码可以工作,但它给了我上面描述的警告。为了摆脱这个问题,我尝试过:
SubscribedUserCount = s?.SubscribedUserCount,
SubscribedRoleCount = s?.SubscribedRoleCount,
不幸的是,这给了我一个错误:“表达式树 lambda 可能不包含空传播运算符”
也许没有解决方案,我当然可以使用#pragma禁用,但我讨厌使用它们,所以我希望有人有更好的主意。
如果您具体化并查看其中的原始数据:
var subscriptionQuery = _dbContext.Subscriptions
.Where(x => x.SiteEntityId == request.SiteGuid)
.GroupBy(x => x.NotificationTypeEntityId, (key, group) => new {
Id = key,
SubscribedUserCount = group.Count(p => p.SubscriberType == Domain.Enums.SubscriberType.User),
SubscribedRoleCount = group.Count(p => p.SubscriberType == Domain.Enums.SubscriberType.Role)
});
如果我不得不猜测,我会怀疑 SubscribedUserCount 和/或 SubscribedRoleCount 值可能为 #null,因此这些值在查询中生成为
int?
。如果是这种情况,那么虽然丑陋,但这应该可行:
SubscribedUserCount = s == null || s.SubscribedUserCount == null
? 0 : s.SubscribedUserCount.Value,
SubscribedRoleCount = s == null || s.SubscribedRoleCount == null
? 0 : s.SubscribedRoleCount.Value,