[英]How do I properly deal with null values and 'where' using LINQ
So I'm in a sticky situation where I have a collection of items of a certain model. For simplicity sake I've made a small model named CarModel
.所以我处于一个棘手的情况,我有一个 model 的项目集合。为了简单起见,我做了一个名为
CarModel
。 In the collection it will have x amount of CarModel
where some of the objects have properties where the value is null.在集合中,它将有 x 数量的
CarModel
,其中一些对象具有值为 null 的属性。
As for right now, it will run the where
LINQ statement just fine on the first 3 items because they are null because it can check whether null == null
.. However, it can't check whether "Test" == null
, hence why I'm currently getting the exception至于现在,它将在前 3 个项目上运行
where
LINQ 语句,因为它们是 null 因为它可以检查是否null == null
..但是,它无法检查是否"Test" == null
,因此为什么我目前得到例外
System.ArgumentNullException: 'Value cannot be null. Parameter name: value'
System.ArgumentNullException:“值不能为 null。参数名称:值”
on this line cars.Where(x => x.Name?.ToLower().Contains(car.Name?.ToLower()) == true).ToList();
在这条线上
cars.Where(x => x.Name?.ToLower().Contains(car.Name?.ToLower()) == true).ToList();
I was thinking about making the Name
property nullable to test if that would work but I'm tied to .NET Framework 4.0
and I'm not allowed to change it so I can't use nullable properties because that required C# 8.0 and the language version is tied to the framework so I'm on C# 7.3我正在考虑使
Name
属性可为 null 以测试它是否可行,但我绑定到.NET Framework 4.0
并且我不允许更改它所以我不能使用可为 null 的属性,因为这需要 C# 8.0 和语言版本绑定到框架,所以我在 C# 7.3
using System.Collections.Generic;
using System.Linq;
using System;
class Program
{
static void Main(string[] args)
{
var car = new CarModel();
car.Name = null;
var cars = new List<CarModel>();
for (int i = 0; i < 3; i++)
{
cars.Add(new CarModel { Name = null });
}
for (int i = 0; i < 3; i++)
{
cars.Add(new CarModel { Name = "Test" });
}
var t = cars.Where(x => x.Name?.ToLower().Contains(car.Name?.ToLower()) == true).ToList();
}
}
internal class CarModel
{
public string Name { get; set; }
public int Year { get; set; }
}
How do I properly filter if some properties might be null at times.如果某些属性有时可能是 null,我该如何正确过滤。 The goal right there is to return a collection of 3 items that it found because it matches the conditions in the WHERE statement.
那里的目标是返回它找到的 3 个项目的集合,因为它符合 WHERE 语句中的条件。
In the provided example car.Name
is always null
, but I assume that you've got an actual use case where that's not always true.在提供的示例中,
car.Name
始终为null
,但我假设您有一个实际用例,但情况并非总是如此。
The exception you're getting is from the Contains
method, which can't handle a null
parameter.您得到的异常来自
Contains
方法,该方法无法处理null
参数。 You'll need to add a check for that, either skipping the entire section (not shown) that deals with the matching list or initialize an empty list when car.Name
is null. Something like:您需要为此添加一个检查,要么跳过处理匹配列表的整个部分(未显示),要么在
car.Name
为 null 时初始化一个空列表。类似于:
var t = car.Name is null ? new List<CarModel>() :
cars.Where
(
x => x.Name?.Contains(car.Name, StringComparison.InvariantCultureIgnoreCase) == true
).ToList();
That's assuming that you don't want to match null
with null
(as Yong Shun's answer does).这是假设您不想将
null
与null
匹配(正如 Yong Shun 的回答那样)。
To be honest though, it might make more sense to ensure that your CarModel
object doesn't accept null
name values.老实说,确保您的
CarModel
object 不接受null
名称值可能更有意义。 Required a name in the constructor, use a property setter that throws on null
and so on.在构造函数中需要一个名称,使用一个在
null
上抛出的属性设置器等等。 Depending on use case, of course.当然,取决于用例。
Just filter out the nulls before using the contains, you can't do a contains on a null value.只需在使用包含之前过滤掉空值,您不能对 null 值执行包含。
var t = cars.Where(x => x.Name != null && x.Name.ToLower().Contains(car.Name)).ToList();
Perhaps you can write the query with dealing with 2 conditions:也许您可以编写处理 2 个条件的查询:
null
, query Name
with null
.null
时,查询Name
为null
。null
, query Name
with not null
and perform a case-insensitive search.null
时,查询Name
不是null
并进行不区分大小写的搜索。or
(fulfill either one).or
(满足其中一个)。var t = cars.Where(x => (car.Name == null && x.Name == null)
|| (car.Name != null && x.Name != null && x.Name.ToLower().Contains(car.Name.ToLower()) == true))
.ToList();
The reason you get the exception error is because Contains method requires non-null argument.您收到异常错误的原因是因为 Contains 方法需要非空参数。
so you should revise your code like below,所以你应该像下面这样修改你的代码,
var t = cars.Where(x => x.Name?.ToLower().Contains(car.Name?.ToLower() ?? string.Empty) == true).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.