Entity Framework Core 1.0.0を使用しているASP.NETコアアプリケーションがあります。Entity Frameworkコア "オブジェクトのインスタンスにオブジェクト参照が設定されていません" LINQのネストされた.Any
特定のクエリで、「オブジェクト参照がオブジェクトのインスタンスに設定されていません」というメッセージが表示されます。
例外の原因となっているクエリである:
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テーブルには、それがどのユーザーに属しているかを示す外部キーがあります。また、ItemDataとUserRoleの間の多数の関係を追跡するItemDataUserRolesテーブルもあります。
残りのクエリは、メソッドに渡すことができるオプションの "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)である:Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.IncludeCore(オブジェクトの実体、INavigationナビゲーション)で
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ナビゲーション、InternalEntityEntryエントリー) Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(queryContext queryContext、オブジェクトの実体、IReadOnlyList 1 navigationPath, IReadOnlyList
1 relatedEntitiesLoaders、のInt32 currentNavigationIndex、ブールqueryStateManager)Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(queryContext queryContext、オブジェクト・エンティティで で、IReadOnlyList 1 navigationPath, IReadOnlyList
1 Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinIncludeでMicrosoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.IncludeでrelatedEntitiesLoaders、ブールqueryStateManager) Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Includeで(オブジェクトの実体) (オブジェクトの実体) .Include(オブジェクトエンティティ) 、Microsoft.EntityFrameworkCore.Query.QueryMethodProvider < _GroupJoin> d__26 4.MoveNext() at System.Linq.Enumerable.<SelectManyIterator>d__163
3.MoveNext()Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor 1.EnumeratorExceptionInterceptor.MoveNext() at System.Collections.Generic.List
1..ctorでSystem.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext() at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__15
2.MoveNext() で(IEnumerableを1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1ソース) Web.ItemHandlers.GenericItemHandler`1.Get(DataContract dataContract、UserAccount user、ItemDbContext dbc) (Web.Controllers.ItemDataController)。(文字列の項目)
あなたのラムダでヌルをチェックしてみましたか?例えば: 's.User.Roles.Any(トン=> r.UserRoleId = NULL && t.RoleId == r.UserRoleId!)' – Meloviz
または二つの別々のステートメントの代わりに、一つの長い文を使用してみてください.... – tCoe
私の最初の幸運なことに、Rolesがnullであることになるので、最初にnullチェックを行うとします。 – thsorens