渲染视图时foreach上的奇数nullreference错误

时间:2010-12-23 11:04:21

标签: c# asp.net-mvc linq-to-entities moq asp.net-mvc-3

这个错误很奇怪我只是无法弄清楚究竟是什么错误!

在UserController中我有

public virtual ActionResult Index()
{
    var usersmdl = from u in RepositoryFactory.GetUserRepo().GetAll()
                   select new UserViewModel
                   {
                       ID = u.ID,
                       UserName = u.Username,
                       UserGroupName = u.UserGroupMain.GroupName,
                       BranchName = u.Branch.BranchName,
                       Password = u.Password,
                       Ace = u.ACE,
                       CIF = u.CIF,
                       PF = u.PF
                   };
    if (usersmdl != null)
    {
        return View(usersmdl.AsEnumerable());
    }
    return View();
}

我的观点是顶部的@model IEnumerable<UserViewModel>类型 这就是:

alt text

在哪里以及究竟是什么无效!?

我使用 moq 从假存储库创建用户。我还编写了单元测试,通过,以确保返回适量的模拟用户。

也许有人能指出我正确的方向吗?堆栈顶部的跟踪是:

at lambda_method(Closure , User )
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at ASP.Index_cshtml.Execute() 

这与linq有关吗?告诉我如果我应该包括完整的堆栈跟踪。


修改
<BangsHeadOnWall /> 哇,我简直不敢相信u.UserGroupMain.GroupName感谢 @Lunivore 这是一个模型仓库,我有一个单元测试来检查模拟repo用户是否有一个UserGroupMain的模拟实例但是如果已经设置了wee属性GroupName我没有Assert !

感谢 @ RPM1984 你建议得到代码在控制器本身中断。另外,我学到了一些新东西。

谢谢 @Mikael ,我第一次使用immediate window哇酷了! = d

猜猜你的生活,编码和学习!

3 个答案:

答案 0 :(得分:6)

是的,它与linq有关。 Linq在您使用它之前不会执行查询。因此,当您循环查询时,查询会运行,并且由于某种原因它会崩溃。

什么是GetAll返回?你可以做的一件事是在Index()中放置一个断点,当它断开时在立即窗口中写下它。

>RepositoryFactory.GetUserRepo().GetAll().ToList()

如果找不到立即窗口,可以通过编写

打开它
>immed

在搜索框中(位于VS的顶部)

如果没有崩溃,问题可能出在Index()内的linq中。从我所看到的,我怀疑u.UserGroupMain或u.Branch为null。但没有更多的信息很难说。

答案 1 :(得分:5)

更改此行:

return View(usersmdl.AsEnumerable());

对此:

return View(usersmdl.ToList());

为什么?

来自MSDN:

  

AsEnumerable(Of TSource)(IEnumerable(Of TSource))方法除了将源代码的编译时类型从实现IEnumerable(Of T)的类型更改为IEnumerable(Of T)本身外无效。 / p>

英文 - 由于.AsEnumerable()转换为IEnumerable<T>,但IQueryable<T> 已经实现IEnumerable<T>,因此查询未实现 - 并且当您枚举foreach中的项目时,在视图中进行延迟评估。 LINQ的经典技巧延迟执行。

这就是为什么我喜欢Resharper - 它会告诉你AsEnumerable()调用是多余的 - 然后你的查询将被推迟变得更加明显。

.ToList()会在查询到达View之前触发查询,并仍然实现IEnumerable<T>,因此您的模型绑定不需要更改。

答案 2 :(得分:1)

检查您在用户中设置的UserGroupMainBranch是否为空:

                   UserGroupName = u.UserGroupMain.GroupName,
                   BranchName = u.Branch.BranchName,

如果这样可以解决您的问题,那么Mikael的回答可以解释为什么会发生这种情况,而不会在查询中进一步解释。