0

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.User.Roles.Any"절을 제거하면

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

(그러나 나에게 내가 원하는 결과를 제공하지 않습니다) :

그러나, 실제 범인 것으로 보인다. 분명히, 나는 사용자 역할 데이터와 교차 체크를 얻기 위해 별도의 쿼리를 할 수 있지만, 수동으로 분리하기 전에 나는 바보 같은 것을 놓치지 않도록하고 싶다. 나는 뇌가 튀었을 때 무슨 일이 일어나는지 알아 내려고 애 쓰면서 많은 시간을 보냈다.

id 및 itemName에 대한 필터링을 제거하면 쿼리가 올바르게 작동하고 사용자에게 속한 항목이나 사용자가 속한 역할을 올바르게 반환하는 것으로 나타납니다. 다음은

이 스택 트레이스입니다 (의 InnerException가 null) : Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.IncludeCore에서

at lambda_method(Closure , InternalEntityEntry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimpleFullyNullableDependentKeyValueFactory1.TryCreateFromCurrentValues(InternalEntityEntry entry, TKey& key) at Microsoft.EntityFrameworkCore.Query.Internal.WeakReferenceIdentityMap 1.CreateIncludeKeyComparer (INavigation 네비게이션, InternalEntityEntry 항목) (개체 개체, INavigation 탐색) Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include에서 Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include (QueryContext queryContext 오브젝트 엔티티 IReadOnlyList 1 navigationPath, IReadOnlyList 1 relatedEntitiesLoaders, INT32 currentNavigationIndex 부울 queryStateManager) 에서 (QueryContext queryContext 오브젝트 실체 , IReadOnlyList 1 navigationPath, IReadOnlyList 1 Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude에서 relatedEntitiesLoaders, Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include에서 Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include (개체 개체) 에서 부울 queryStateManager) (개체 개체) .Exclude (개체 엔터티) at 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.Get (String item)

+0

람다에서 null을 확인해 보셨습니까? 예 : :'s.User.Roles.Any (t => r.UserRoleId! = null && t.RoleId == r.UserRoleId)' – Meloviz

+0

또는 하나의 long 문 대신에 두 개의 별도의 문을 사용해보십시오 .... – tCoe

+0

내 첫 번째 문구 행운의 추측은 Roles가 null이 될 것이므로, 먼저 null 체크를하면된다. – thsorens

답변

0

내 쿼리에 정말 바보 같은 오류가 발생했습니다.

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

나는 그러나, 그때 내 항목을 일치 만 내 항목에 대한 ItemDataUserRoles의 목록을 필터링하고, 현재 항목의 ItemDataUserRoles에 접근했다. 분명히, 완전히 여분의 수표. 그러나 이것은 그것을 깨뜨리지 못했습니다. 그것을 깨뜨린 것은 내가 한 일은 그 ItemDataUserRoles가 전달 된 사용자 대신 원래 ItemData 행의 사용자와 일치하는지 확인하는 것입니다. 이것은 잘못된 결과를주는 기묘한 SQL 쿼리를 생성하고있었습니다.