我的查询在找不到任何项目时应该返回null吗?

时间:2013-11-01 16:15:05

标签: c# asp.net-mvc linq entity-framework

我有一个multiselectlist,用户可以选择一些inputvoltages。当用户选择不InputVoltages时,当我拨打null exception时,我的查询会引发.Tolist()。为什么我不只是回到空名单?

我正在使用MVC5 C#和实体框架6。

存储库

public IQueryable<InputVoltage> All
{
    get { return context.InputVoltages; }
}

控制器

var newInputVoltages = unitOfWorkPds.InputVoltageRepository
    .All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages
        .Contains(m.Id))
    .ToList<InputVoltage>();

All会返回一个列表,但如果未选择任何内容,则SelectedInputVoltages为空。我想知道这是不是问题。

当我使用此查询并为索引页面添加where语句时,当我调用ToList

时,我不会收到空错误
IQueryable<EngineeringPdsIndexViewModel> query = 
    (from a in context.EngineeringPds
     select new EngineeringPdsIndexViewModel
     {
         Id = a.Id,
         Name = a.Name,
         Status = a.Status,
         AnnualQuantities = a.AnnualQuantities,
         ToMarketDate = a.ToMarketDate,
         SubmittedBy = a.SubmittedBy,
         TargetPrice = a.TargetPrice
     });

所以我相信Brian对错误有正确的认识,但问题在于扩展 我有一个多选框,在

的get动作方法中填充
    IList<InputVoltage> inputVoltagesList = unitOfWorkPds.InputVoltageRepository.All.ToList();

然后

pdsEditViewModel.InputVoltageList = inputVoltagesList.Select(m => new SelectListItem { Text = m.Name, Value = m.Id.ToString() });  in my view I hav@Html.ListBoxFor(m => m.SelectedApprovals, Model.ApprovalList)

但是当用户没有选择时,selectedInputvoltages作为null进入我的帖子控制器操作,如何让它作为空列表进入?

更新

对于遇到同样问题的人,Brians第一个回答解释了这个问题。可以在此处找到提交带有空列表的ListBox的工作

How can I return an empty list instead of a null list from a ListBoxFor selection box in Asp.net MVC?

4 个答案:

答案 0 :(得分:3)

BCL中为IEnumerable<T>IQueryable<T>定义的返回IEnumerable<T>IQueryable<T>的任何扩展方法都不会返回null。它可能会返回一个空集合,但这与null非常不同。

试试这个:

var newInputVoltages = engineeringPdsEditViewModel.SelectedInputVoltages == null ?
    unitOfWorkPds.InputVoltageRepository.All : 
    unitOfWorkPds.InputVoltageRepository.All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages.Contains(m.Id)).ToList();

答案 1 :(得分:2)

哪里不会返回null。问题在于论证:

engineeringPdsEditViewModel.SelectedInputVoltages.Contains(m.Id)

NULL engineeringPdsEditViewModel或SelectedInputVoltages可能导致NullReferenceException被抛出。所以你需要对这些对象进行空检查。

你可以看到这个类似的测试样本。这里我们得到一个nullrefex因为myString为空。因此,当Where执行时,它会尝试进行比较并炸毁:

       var test = new TestClass(1);
        var test2 = new TestClass(2);
        var test3 = new TestClass(3);

        List<TestClass> tests = new List<TestClass>();
        tests.Add(test);
        tests.Add(test2);
        tests.Add(test3);

        string myString = null;

        var result = tests.Where(t => myString.Contains(t.Myint.ToString())).ToList();
        Console.WriteLine(result.Count);

更新:(回答您的评论)

您可以返回如下的空列表:

List<InputVoltage> newInputVoltages = new List<InputVoltage>();
if(engineeringPdsEditViewModel != null && engineeringPdsEditViewModel.SelectedInputVoltages != null)
{
     //Where params are not null so its safe to use them
     newInputVoltages = unitOfWorkPds.InputVoltageRepository
    .All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages
    .Contains(m.Id))
    .ToList<InputVoltage>();
}
//else no need to do anything...just return the empty list created above
return newInputVoltages;

答案 2 :(得分:0)

你不会得到一个空列表,它的预期行为会返回null。

答案 3 :(得分:0)

在创建变量时测试输入(我使用Ternary Operator),稍后您不需要任何验证

var newInputVoltages = SelectedInputVoltages.Any() 
          ?  unitOfWorkPds.InputVoltageRepository
                .All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages.Contains(m.Id))
                .ToList<InputVoltage>()
          : new List<InputVoltage>();