Entity Framework 核心 "Object reference not set to an instance of an object" 与 LINQ 中的嵌套 .Any

Entity Framework Core "Object reference not set to an instance of an object" with nested .Any in LINQ

我有一个 ASP.NET Core 应用程序使用 Entity Framework Core 1.0.0.

在特定查询中,我收到 "Object reference not set to an instance of an object" 异常。

导致异常的查询是:

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

查询的目标是 return 一个完全填充的 ItemData 对象,其中项目属于用户或属于用户所属的任何角色。 ItemData table 有一个指向 User 的外键,指示它属于哪个用户。还有一个 ItemDataUserRoles table 跟踪 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 的过滤,查询工作正常并且似乎正确 return 属于用户或用户所属角色的项目.

下面是堆栈跟踪(InnerException 为空):

在 lambda_method(闭包,InternalEntityEntry) 在Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimpleFullyNullableDependentKeyValueFactory<code>1.TryCreateFromCurrentValues(InternalEntityEntry entry, TKey& key) at Microsoft.EntityFrameworkCore.Query.Internal.WeakReferenceIdentityMap1.CreateIncludeKeyComparer(INavigation 导航,InternalEntityEntry 条目) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.IncludeCore(对象实体,INavigation 导航) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(QueryContext queryContext,对象实体,IReadOnlyList1 navigationPath, IReadOnlyList1 relatedEntitiesLoaders,Int32 currentNavigationIndex,Boolean queryStateManager) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(QueryContext queryContext,对象实体,IReadOnlyList1 navigationPath, IReadOnlyList1 relatedEntitiesLoaders,Boolean queryStateManager) 在 Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(对象实体) 在 Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(对象实体) 在 Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(对象实体) 在 Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_GroupJoin>d__264.MoveNext() at System.Linq.Enumerable.<SelectManyIterator>d__1633.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__152.MoveNext() 在 Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor1.EnumeratorExceptionInterceptor.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 来源) 在 Web.ItemHandlers.GenericItemHandler`1.Get(DataContract dataContract, UserAccount user, ItemDbContext dbc) 在 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 查询,该查询给出了错误的结果。