测试期间Linq出错,但不是运行时

时间:2015-11-25 17:58:23

标签: c# linq

在我的MVC控制器ActionResult中,我尝试进行合并类型的查询。这在我运行我的代码时有效,但ActionResult的单元测试失败。

首先,我获得了revResources个特定资源的集合,如果有的话。可能没有。

然后我使用DefaultIfEmpty获取加入projResources的资源列表(revResources)。

在测试期间,我在内存中找到了projResources类型为System.Linq.IQueryable'的对象,但当我尝试获取List()时,我得到:

  

NullReferenceException未被用户代码

处理

我不确定什么是null,或者为什么这在运行时有效但在测试期间无效。

在测试期间,db.RoleAssignmentdb.ProfileSnapshot都包含正确关联的有效记录。我通过尝试select raselect p来测试了这一点。

以下是有问题的代码:

var revResources = (from ra in db.RoleAssignment
                    where ra.RoleId == (int)SystemRoles.viewReview
                    select ra)
                .Distinct();
// At Runtime this may have zero (0) records and still functions.

var projResources = (from ra in db.RoleAssignment
                        join p in db.ProfileSnapshot on ra.AssigneeId equals p.ProfileSnapshotId
                        join r in revResources on ra.AssigneeId equals r.AssigneeId into rres
                        from r in rres.DefaultIfEmpty()
                        where ra.AssignedToId == review.RequestReview.ProjectSubmissionToReview.ProjectId
                        select new ProfileSnapshotViewModel
                        {
                            ProfileSnapshotId = p.ProfileSnapshotId,
                            Salutation = p.Salutation,
                            FirstName = p.FirstName,
                            MiddleName = p.MiddleName,
                            LastName = p.LastName,
                            Email = p.Email,
                            OriginalSelected = r.RoleAssignmentId != null,
                            Selected = r.RoleAssignmentId != null,
                            RoleAssignmentId = r.RoleAssignmentId
                        }).Distinct();

var assignedResList = projResources.ToList(); // This code fails

错误详细信息中的StackTrace如下所示:

at lambda_method(Closure , <>f__AnonymousType17`2 )
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.<DistinctIterator>d__81`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at PublicationSystem.Controllers.ProjectController.ReviewResourceDetails(Guid id) in c:\Projects\BitLocker\publicationsystem\PublicationSystem\Controllers\ProjectController.cs:line 1200
at PublicationSystem_Test.Controllers.ProjectTests.Project_ReviewResourceDetails_Test() in c:\Projects\BitLocker\publicationsystem\PublicationSystem_Test\Controllers\ProjectTests.cs:line 74

1 个答案:

答案 0 :(得分:0)

问题在于:

.....
from r in rres.DefaultIfEmpty()
..... 

您已经容忍DefaultIfEmpty()值,这意味着LINQ查询可能会为r条目返回NULL。

否则,您尝试在select子句

中访问r的属性
 // What should be the value of RoleAssignmentId  if r is null ? 
OriginalSelected = r != null && r.RoleAssignmentId != null,
Selected = r != null && r.RoleAssignmentId != null,
RoleAssignmentId = r == null ? null : r.RoleAssignmentId 

使用ToList()引发异常,因为LINQ查询仅在重新登录时运行。

有一个关于here

的非常明确的话题