簡體   English   中英

對於IQueryable,EF Core Include()語句為null

[英]EF Core Include() statement is null for IQueryable

好的,因此如果沒有大量代碼來支持它可能會有點難以解釋,但我會盡力而為。

本質上,我正在執行一個涉及一對多關系的查詢(當前在ef核心2.1上)。 但是,“許多”集合在實現時為空。

這是有問題的查詢(為簡潔起見刪除了一些代碼)

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);
}

但是,這將引發null引用異常,因為Users集合為null。 現在我的問題是,當我明確要求加載時,為什么Users集合為null? 目前的一種解決方法是將查詢的第一行更改為_managedSupportRepository.GetAllIncluding(m => m.Users).AsEnumerable() ,這很可笑,因為它將所有記錄都帶回了(幾千條),因此性能是不存在的。

它必須是IQueryable的原因是可以應用分頁,從而減少了從數據庫中提取的信息量。

任何幫助表示贊賞。

此問題有兩個部分:

1)不包含在投影中不包含在內

當您在提供程序上對EF進行查詢(服務器評估)時,您不會“執行” new表達式,因此:

ActiveUsers = ms.GetConsumed(),

從不實際執行ms.GetConsumed() 您將為new傳遞的表達式進行解析,然后轉換為查詢(對於sql server,為SQL),但是不會在提供程序上(對數據庫的查詢ms.GetConsumed()執行ms.GetConsumed() )。

因此,您需要在表達式上包括Users 例如:

select new AccountViewModel
{
    AccountName = a.AccountName,
    AllUsers = Users.ToList(),
    ActiveUsers = ms.GetConsumed(),
    // etc.
}

這樣,EF知道它需要Users查詢並實際包含它(您沒有在表達式中使用Users ,因此EF認為即使您Include()它也不需要它...它可能會顯示警告(在Visual Studio的“ Output窗口中),否則它將嘗試投影並僅請求new表達式(不包括Users )中理解的字段。

因此,您需要在此處明確...嘗試:

ActiveUsers = Users.Count(u => !u.IsDeleted && u.Enabled && u.UserType == UserType.Active);

並且實際上將包括Users

2)無法翻譯查詢時自動進行客戶端評估

在這種情況下,將包含Users因為它在實際的表達式中... 但是 ,EF仍然不知道如何將ms.GetConsumed()轉換為提供程序查詢,因此它將起作用(因為將加載Users ) ,但不會在數據庫上運行,它仍將在內存上運行(它將進行客戶端投影)。 同樣,如果在Visual Studio的“ Output窗口中運行它,則應該在此看到警告。

EF Core允許這樣做(EF6不允許),但是您可以將其配置為在發生這種情況時引發錯誤(在內存中評估查詢):

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        /* etc. */
        .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
}

您可以在此處閱讀有關此內容的更多信息: https : //docs.microsoft.com/zh-cn/ef/core/querying/client-eval

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM