實體框架核心“對象引用未設置為對象的實例”在LINQ中具有嵌套的.Any

asp.net-core-1.0 asp.net-core-mvc c# entity-framework-core linq

我有一個使用Entity Framework Core 1.0.0的ASP.NET核心應用程序。

在特定的查詢中,我得到一個“對象引用未設置為對象的實例”異常。

導致異常的查詢是:

            return mContext.ItemDatas
            .Include( a => a.ItemDataUserRoles )
            .Include( b => b.Item )
            .Include( c => c.User ).ThenInclude( d => d.Roles )
            .Where(
                s =>
                    ( s.User.Id == user.Id ||
                      s.ItemDataUserRoles.Any( r => r.ItemDataId == s.Id &&
                                                      s.User.Roles.Any( t => t.RoleId == r.UserRoleId ) ) ) &&
                    ( string.IsNullOrEmpty( id ) || s.Id == id ) &&
                    ( string.IsNullOrEmpty( itemName ) || s.Item.ItemName.ToLower() == itemName.ToLower() ) &&
                    s.IsActive );

查詢的目標是返回一個ItemData對象,該對象完全填充該項屬於User或屬於該用戶所屬的任何角色。 ItemData表具有User的外鍵,用於指示它所屬的用戶。還有一個ItemDataUserRoles表,用於跟踪ItemData和UserRole之間的多對多關係。

查詢的其餘部分是基於可以傳遞給方法的可選“id”和“itemName”來過濾結果。

看似null的特定對像是s.Item。如果我將“s.Item.ItemName.ToLower()”更改為s.ItemId.ToLower(),它可以正常工作。

然而,實際的罪魁禍首似乎是:

s.ItemDataUserRoles.Any( r => r.ItemDataId == s.Id &&
                                                      s.User.Roles.Any( t => t.RoleId == r.UserRoleId ) ) ) &&

如果我刪除“s.User.Roles.Any”部分它工作正常(但不會給我我需要的結果)。顯然,我可以做一個單獨的查詢來獲取用戶角色數據和交叉檢查,但在我手動將它分開之前,我想確保我不會錯過一些愚蠢的東西。我花了很多時間試圖弄清楚我腦子裡的油炸是怎麼回事。

還值得注意的是,如果我刪除對id和itemName的過濾,則查詢工作正常並且似乎正確地返回屬於用戶的項目或用戶所屬的角色。

下面是堆棧跟踪(InnerException為null):

at lambda_method(Closure , InternalEntityEntry ) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimpleFullyNullableDependentKeyValueFactory 1.TryCreateFromCurrentValues(InternalEntityEntry entry, TKey& key) at Microsoft.EntityFrameworkCore.Query.Internal.WeakReferenceIdentityMap 1.CreateIncludeKeyComparer(INavigation navigation, InternalEntityEntry entry) at Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.IncludeCore(Object entity, INavigation navigation) at Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(QueryContext queryContext, Object entity, IReadOnlyList 1 navigationPath, IReadOnlyList 1 relatedEntitiesLoaders, Int32 currentNavigationIndex, Boolean queryStateManager) at Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(QueryContext queryContext, Object entity, IReadOnlyList 1 navigationPath, IReadOnlyList 1 relatedEntitiesLoaders, Boolean queryStateManager) at Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(Object entity) at Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(Object entity) at Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(Object entity) at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_GroupJoin>d__26 4.MoveNext() at System.Linq.Enumerable.<SelectManyIterator>d__163 3.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext() at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__15 2.MoveNext() at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor 1.EnumeratorExceptionInterceptor.MoveNext() at System.Collections.Generic.List 1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1 source) at Web.ItemHandlers.GenericItemHandler`1.Get(DataContract dataContract, UserAccount user, ItemDbContext dbc) at Web.Controllers.ItemDataController.Get(String item)

一般承認的答案

我的查詢中有一個非常愚蠢的錯誤。

              s.ItemDataUserRoles.Any( r => r.ItemDataId == s.Id &&
              s.User.Roles.Any( t => t.RoleId == r.UserRoleId ) ) ) &&

我正在訪問當前項目的ItemDataUserRoles,但是,我正在將我的項目的ItemDataUserRoles列表過濾到僅與我的項目匹配的項目。顯然,一個完全冗餘的檢查。然而,這並沒有打破它。破壞它的是我接下來要做的就是檢查那些ItemDataUserRoles是否匹配原始ItemData行上的用戶而不是傳入的用戶。這創建了一個奇怪的SQL查詢,給出了錯誤的結果。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因