EntityFramework获取数据库中价格最低的两个对象空引用异常问题
解决空引用异常并优化获取价格最低两款产品的代码
嘿,我来帮你捋捋问题出在哪,以及怎么修复~
首先,你的空引用异常根源很明确:
as List<Product>转换失败得到null:db.Products.Include(...).OrderBy(...)返回的是IQueryable<Product>对象,它根本不是List<Product>的实例,用as转换的时候会直接返回null,后面访问list[0]自然就炸了。- 多此一举的List转换:你完全没必要先把查询结果转成List再取元素,用LINQ的
Take(2)就能直接获取排序后的前两个元素,而且这个操作会被翻译成SQL,让数据库只返回两条数据,性能比你先拉全表再处理好太多。 - 错误的返回类型转换:最后用
retVal as IQueryable<Product>也不对,List<T>本身并不实现IQueryable<T>,要转的话得用AsQueryable()方法才行。
下面给你两种修复后的代码方案,按需选用:
方案1:直接返回IQueryable(推荐,保留延迟执行)
如果你希望调用方还能继续扩展这个查询(比如再加个过滤条件),那直接返回IQueryable是最优解,查询会延迟到调用方遍历结果时才执行:
public IQueryable<Product> GetTwoWithLowestPrice() { return db.Products .Include(p => p.Category) .OrderBy(p => p.Price) .Take(2); }
方案2:立即执行查询并返回集合
如果需要立即触发数据库查询(比如要确保数据是最新的,或者后续要对集合做内存操作),可以先转成List,再按需转成IQueryable:
public IQueryable<Product> GetTwoWithLowestPrice() { var lowestTwoProducts = db.Products .Include(p => p.Category) .OrderBy(p => p.Price) .Take(2) .ToList(); // 这里立即执行查询 return lowestTwoProducts.AsQueryable(); }
另外还要提个边界情况:如果数据库里产品数量不足2个,直接取list[0]或list[1]会抛出索引越界异常,而用Take(2)就会自动返回现有数量的产品(比如只有1个就返回1个,没有就返回空集合),安全性更高。
内容的提问来源于stack exchange,提问作者Context
相关产品推荐
相关产品推荐

