运行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
。我检查了变量,它正在返回一个餐馆名称。但我不明白为什么我会收到这些错误。
答案 0 :(得分:4)
问题是你的linq查询返回一个空集合:
from r in objCtx.Restaurants
where r.id == item.restaurantid
select r
在第一个示例中调用SingleOrDefault
时,它会返回null
(即默认值)。您收到object reference not set ...
,因为您尝试在空引用上调用Name
属性。
在第二个示例中,您拨打Single
。当您在包含0或+1元素的列表上执行此操作时,将引发异常。 (正如您所经历的那样)。
解决方案是确保始终检索单个实例,或在访问该对象的任何属性之前进行检查
答案 1 :(得分:2)
正如其他人所说,你的结果集是空的。这将导致Single
失败(这是记录的),并且它将导致SingleOrDefault
返回给定类型的默认值(在类的情况下为null
)。
除了其他答案(使用空值守卫)中提供的解决方案之外,还有另一个使用更多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" }
的默认值,创建一个匿名对象,但这取决于你。
答案 2 :(得分:0)
问题是集合中没有满足条件的项目。 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;
答案 3 :(得分:0)
如果如你所说,你的第二个代码示例(使用Single
的那个)没有返回任何元素,那么第一个(使用SingleOrDefault
的代码)返回null
。并且您无法从.Name
获取null
属性。
我认为您需要验证您的查询。直接查看数据,或者甚至只是遍历数据并查看输出结果:
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;
答案 4 :(得分:0)
如果序列中没有项目,则单个将通过异常。
尝试:
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;