asp.net Linq对象引用不是对象的示例

cbwuti44  于 2023-01-27  发布在  .NET
关注(0)|答案(6)|浏览(111)

Linq查询运行时遇到问题,收到错误Object reference not set to an instance of an object.

var RestaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).SingleOrDefault<Restaurant>().Name;

然后我将查询更改为

var RestaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).Single<Restaurant>().Name;

但是我收到了错误Sequence contains no elements。我检查了变量,它返回了一个餐馆名称。但是我不明白为什么我会收到这些错误。

mtb9vblg

mtb9vblg1#

问题是您的linq查询返回一个空集合:

from r in objCtx.Restaurants
where r.id == item.restaurantid
select r

当你在第一个例子中调用SingleOrDefault时,它会返回null(即默认值),你会收到一个object reference not set ...,因为你试图在一个空引用上调用Name属性。
在第二个例子中,我们调用了Single。当你在一个包含0或+1个元素的列表中调用Single时,将会抛出一个异常(正如你所经历的那样)。
解决方案是确保始终检索单个示例,或者在访问该对象的任何属性之前进行检查

wydwbb8l

wydwbb8l2#

正如其他人所说,您的结果集是空的,这将导致Single失败(这是有文档记录的),并且它将导致SingleOrDefault返回给定类型的默认值(对于类,null)。
除了其他答案中介绍的解决方案(使用null guard),这里还有一个使用更多LINQ的解决方案:

var RestaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).DefaultIfEmpty(new Restaurant() { Name="None" })
                               .SingleOrDefault().Name;

DefaultIfEmpty会将SingleOrDefault返回的“默认”值从null更改为提供的值。这样,您就可以安全地访问Name属性。根据Restaurant类的具体构建方式,您可能希望以不同的方式创建默认值。您还应该能够提供类似new { Name = "None" }的默认值,创建一个匿名对象但这取决于你。

hiz5n14c

hiz5n14c3#

问题是集合中没有满足条件的项。SingleOrDefault返回null(对于引用类型),因此在第一个版本中,您将收到NullReferenceException。如果没有返回元素,Single将抛出异常,这就是第二种方法失败的原因。
您需要检查是否有任何结果:

var restaurant = (from r in objCtx.Restaurants
                  where r.id == item.restaurantid
                  select r).SingleOrDefault<Restaurant>();
string restaurantName;
if (restaurant != null)
    restaurantName = restaurant.Name;
else
    restaurantName = string.Empty;
mccptt67

mccptt674#

如前所述,如果第二个代码示例(使用Single的代码示例)没有返回元素,那么第一个代码示例(使用SingleOrDefault的代码示例)返回null,并且无法从null中获取.Name属性。
我认为您需要验证您的查询。直接查看数据,或者甚至只是循环查看数据,看看输出是什么:

var restaurants = from r in objCtx.Restaurants
                  where r.id == item.restaurantid
                  select r;

foreach (var restaurant in restaurants)
{
    string name = restaurant.Name;
}

我猜这个循环永远不会执行,因为它是空的,您需要找出查询中的错误。
如果您需要处理可能不返回元素的场景,那么您只需要一个if检查:

var restaurant = (from r in objCtx.Restaurants
                  where r.id == item.restaurantid
                  select r).SingleOrDefault<Restaurant>();

string restaurantName;
if (restaurant == null)
    restaurantName = string.Empty;
else
    restaurantName = restaurant.Name;
jyztefdp

jyztefdp5#

试试看:

var RestaurantName = ((from r in objCtx.Restaurants
                          where r.id == item.restaurantid
                          select r).Any()) ? (from r in objCtx.Restaurants
                          where r.id == item.restaurantid
                          select r).SingleOrDefault<Restaurant>().Name : string.empty;
yi0zb3m4

yi0zb3m46#

var restaurantName = new Restaurant();

restaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).SingleOrDefault(); 

var RestaurantName = (restaurantName != null) ? restaurantName.Name : "";

相关问题