【发布时间】:2018-07-26 15:44:48
【问题描述】:
好的,如果没有大量代码来支持它,这可能有点难以解释,但我会尽力而为。
基本上我正在做一个查询(目前在 ef core 2.1 上),其中涉及一对多的关系。但是,“many”集合在具体化时为空。
这是有问题的查询(为简洁起见,删除了一些代码)
IQueryable<AccountViewModel> baseQuery = from ms in _managedSupportRepository.GetAllIncluding(m => m.Users) // here is the problem
// a few lines of filters like the one below
where string.IsNullOrEmpty(clientVersionFilter) || !string.IsNullOrEmpty(ms.ClientVersion) && ms.ClientVersion.Contains(clientVersionFilter, StringComparison.OrdinalIgnoreCase)
join c in _contractRepository.GetAll() on ms.Id equals c.AssetId into contracts
from c in contracts.DefaultIfEmpty()
let isAssigned = c != null
where !isAssignedFilter.valueExists || isAssignedFilter.value == isAssigned
join a in _autotaskAccountRepository.GetAll() on ms.TenantId equals a.Id
where string.IsNullOrEmpty(accountNameFilter) || !string.IsNullOrEmpty(a.AccountName) && a.AccountName.Contains(accountNameFilter, StringComparison.OrdinalIgnoreCase)
select new AccountViewModel
{
AccountName = a.AccountName,
ActiveUsers = ms.GetConsumed(), // here is the problem
ClientVersion = ms.ClientVersion,
ExternalIpAddress = ms.IpAddress,
Hostname = ms.Hostname,
Id = ms.Id,
IsActive = ms.IsActive,
IsAssigned = isAssigned,
LastSeen = ms.CheckInTime,
Status = ms.Status
};
int count = baseQuery.Count();
baseQuery = baseQuery.Paging(sortOrder, start, length);
return (baseQuery.ToList(), count);
为了清楚起见,_managedSupportRepository.GetAllIncluding(m => m.Users) 方法只是 .Include() 方法的包装。
所以问题出在活动用户ActiveUsers = ms.GetConsumed(), 的视图模型中。 GetConsumed()方法如下
public long GetConsumed()
{
return Users.Count(u => !u.IsDeleted && u.Enabled && u.UserType == UserType.Active);
}
但是,这会引发空引用异常,因为用户集合为空。
现在我的问题是,当我明确要求加载用户集合时,为什么它是空的?
目前的解决方法是将查询的第一行更改为 _managedSupportRepository.GetAllIncluding(m => m.Users).AsEnumerable(),这太荒谬了,因为它会将所有记录带回(几千条),因此性能不存在。
它需要是 IQueryable 的原因是可以应用分页,从而减少从数据库中提取的信息量。
感谢任何帮助。
【问题讨论】:
标签: c# entity-framework entity-framework-core ef-core-2.1