实体框架核心“对象引用未设置为对象的实例”,嵌套 .任何在 LINQ 中

本文关键字:实例 嵌套 任何 LINQ 对象 核心 框架 对象引用 设置 实体 | 更新日期: 2023-09-27 17:56:20

我有一个使用实体框架核心 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 对象,其中该项属于用户或属于用户所属的任何角色。ItemData 表具有指向 User 的外键,该外键指示它属于哪个用户。还有一个 ItemDataUserRoles 表,用于跟踪 ItemData 和 UserRole 之间的多对多关系。

查询的其余部分是根据可传递到方法中的可选"id"和"itemName"筛选结果。

显示为空的特定对象是 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 为空):

at lambda_method(Closure , InternalEntityEntry ) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimpleFullyNullableDependentKeyValueFactory1.TryCreateFromCurrentValues(InternalEntityEntry entry, TKey& key) at Microsoft.EntityFrameworkCore.Query.Internal.WeakReferenceIdentityMap 1.创建包含键比较器(内部导航,内部实体条目) 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)

实体框架核心“对象引用未设置为对象的实例”,嵌套 .任何在 LINQ 中

我的查询中有一个非常愚蠢的错误。

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

我正在访问当前项目的 ItemDataUserRoles,但是,我随后将我的项目的 ItemDataUserRoles 列表过滤为仅与我的项目匹配的那些。显然,这是完全多余的检查。然而,这并没有打破它。破坏它的是我做的下一件事是检查这些 ItemDataUserRoles 是否与原始 ItemData 行上的用户匹配,而不是传递的用户。这创建了一个奇怪的SQL查询,给出了错误的结果。