在linq中使用除==以外的任何其他运算符时,出现空引用错误

时间:2018-07-18 18:07:53

标签: c# linq asp.net-core razor-pages

我目前正在使用ASP-NetCore剃刀页面来创建Web应用程序。其中有两个相似的页面,它们提取两个互补的数据。结果,它们的Pagemodel的代码几乎相同,唯一的区别是使用!=而不是==。尽管如此,使用==的一个运行没有问题,而另一个使用以下错误:

System.NullReferenceException: Object reference not set to an instance of an object.
   at lambda_method(Closure , AccountRequest )
   at System.Linq.AsyncEnumerable.WhereSelectEnumerableAsyncIterator`2.<MoveNextCore>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Linq.AsyncEnumerable.AsyncIterator`1.<MoveNext>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Linq.AsyncEnumerable.<Aggregate_>d__6`3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Webapp.Pages.SalesReps.CompletedAccountRequests.IndexModel.<OnGetAsync>d__10.MoveNext() in fakepath\Pages\SalesReps\CompletedAccountRequests\Index.cshtml.cs:line 30

起作用的代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using WebApp.Data;
using WebApp.Models;

namespace WebApp.Pages.SalesReps.NewAccountRequests
{
    public class IndexModel : PageModel
    {
        private readonly AccessionContext _context;

        public IndexModel(AccessionContext context)
        {
            _context = context;
        }

        public IList<AccountRequest> AccountRequest { get;set; }
        public IList<String> Claims { get; set; }

        public async Task OnGetAsync()
        {
            var claim = from c in User.Claims where c.Type == "SalesRep" select c.Value;
            Claims = claim.ToList();
            var requests = 
                from a in _context.AccountRequests 
                where ((Claims.Contains(a.Group.SalesRep)) 
                    || (Claims.Contains(a.Group.Manager))) 
                    && a.RequestStatus == 0 
                orderby a.RequestDate 
                select a;

            if (requests != null)
            {
                AccountRequest = await requests.ToListAsync();
            }
        }
    }
}

这是导致错误的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using WebApp.Data;
using WebApp.Models;

namespace WebApp.Pages.SalesReps.CompletedAccountRequests
{
    public class IndexModel : PageModel
    {
        private readonly AccessionContext _context;

        public IndexModel(AccessionContext context)
        {
            _context = context;
        }

        public IList<AccountRequest> AccountRequest { get;set; }
        public IList<String> Claims { get; set; }

        public async Task OnGetAsync()
        {
            var claim = from c in User.Claims where c.Type == "SalesRep" select c.Value;
            Claims = claim.ToList();
            var requests = 
                from a in _context.AccountRequests 
                where ((Claims.Contains(a.Group.SalesRep)) 
                    || (Claims.Contains(a.Group.Manager))) 
                    && a.RequestStatus != 0 
                orderby a.RequestDate 
                select a;
            AccountRequest = await requests.ToListAsync();
        }
    }
}

下面是实际页面。

@page
@model WebApp.Pages.SalesReps.CompletedAccountRequests.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<table class="table">
    <thead>
        <tr>
            <th>
                Date Completed
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].PracticeName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].GroupID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].Group.SalesRep)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].RequestedBy)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].RequestDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].RequestStatus)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].ClientIDS)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].CompletedBy)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.AccountRequest[0].CompletedDate)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.AccountRequest) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.CompletedDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.PracticeName)
            </td>
            <th>
                @Html.DisplayFor(modelItem => item.GroupID)
            </th>
            <th>
                @Html.DisplayFor(modelItem => item.Group.SalesRep)
            </th>
            <td>
                @Html.DisplayFor(modelItem => item.RequestedBy)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.RequestDate)
            </td>
            <td>
                @if (item.RequestStatus == 1)
                {
                    Html.Display("Completed");
                } else if(item.RequestStatus == 2)
                {
                    Html.Display("Denied");
                } else if (item.RequestStatus == 3)
                {
                    Html.Display("Under Different Group");
                } else if (item.RequestStatus == 4)
                {
                    Html.Display("Account Closed");
                }
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ClientIDS)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CompletedBy)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CompletedDate)
            </td>
            <td>
                <a asp-page="./Details" asp-route-id="@item.AccountRequestID">Details</a>
            </td>
        </tr>
}
    </tbody>
</table>

为什么使用!=运算符会导致这种错误,我该如何解决?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

对于其中a.RequestStatus != 0评估为true的返回记录之一,Group关系为空,这在为该记录评估a.Group.SalesRepa.Group.SalesRep时将导致NRE( s)。

您可以通过添加检查以检查这种关系是否存在来解决此问题(请参见下文),但是在逻辑上可能不正确(这取决于数据约束和您认为不良数据的原因,实际上更多商业决定)。

var requests = 
    from a in _context.AccountRequests 
    where a.Group != null && // <-- added null check
        ((Claims.Contains(a.Group.SalesRep)) || (Claims.Contains(a.Group.Manager))) 
        && a.RequestStatus != 0 
    orderby a.RequestDate 
    select a;