.NET Core MVC 创建关联Product列表的Order实体空引用异常如何解决
问题原因及修正方案

1 空引用异常直接原因
- Order类的
ProductList导航属性未做初始化,默认值为null,调用AddProducts方法时执行ProductList.ToList()会直接触发空引用异常 - 循环中调用
ProductList.ToList().Add(product)存在逻辑错误:ToList()每次都会生成一个全新的临时集合对象,Add操作是作用在这个临时集合上,执行完就被回收,根本不会把产品保存到Order的ProductList属性中,添加操作完全无效
2 实体设计存在的规范问题
2.1 导航属性类型错误
EF Core中用于增删操作的集合导航属性,不能用IEnumerable<T>类型,该类型只支持遍历,不支持原生的集合修改操作,应当改用ICollection<T>类型。
2.2 缺失无参构造函数
你的Product类只声明了带参数的构造函数,编译器不会自动生成默认无参构造函数,EF Core做数据库实体映射的时候需要无参构造函数来实例化对象,后续查询操作会直接报错。
2.3 多对多关系设计缺失
从业务逻辑来看,Order和Product属于多对多关系,你的现有设计没有中间表关联,也没有存储购买数量、下单时的产品快照价格的字段,不符合实际业务需求,后续会出现数据覆盖、无法统计购买数量等问题。
3 修正后的代码示例
修正后的Product类
using System.ComponentModel.DataAnnotations; namespace Domain.Entities { public class Product { [Key] public int ProductID { get; set; } [Required] public string ProductName { get; set; } [Required] public int ProductPrice { get; set; } // 补充EF Core需要的无参构造函数 public Product() { } public Product(string productName, int productPrice) { ProductName = productName; ProductPrice = productPrice; } public void ApplyDiscounts(int discountValue) { // 原逻辑判断写反,折扣大于等于产品价格时减完会出现负数,已修正 if (discountValue <= this.ProductPrice) { this.ProductPrice -= discountValue; } } } }
修正后的Order类
using Domain.Entities; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; namespace Project.Domain.Entities { public class Order { [Key] public int OrderId { get; set; } // 改用ICollection,同时初始化属性避免空引用 public virtual ICollection<Product> ProductList { get; private set; } = new List<Product>(); public Order() { } public Order AddProducts(IEnumerable<Product> productListToAdd) { // 直接添加到现有集合,无需每次生成临时List foreach (var product in productListToAdd) { ProductList.Add(product); } return this; } } }
4 业务优化建议
如果要符合实际生产业务,建议新增OrderItem中间表存储关联关系,示例结构如下:
public class OrderItem { [Key] public int Id { get; set; } public int OrderId { get; set; } public int ProductId { get; set; } // 存储下单时的产品价格,避免后续产品改价导致订单数据错乱 public int SnapshotPrice { get; set; } // 存储购买数量 public int Quantity { get; set; } public virtual Order Order { get; set; } public virtual Product Product { get; set; } }
之后把Order类中的ProductList改为ICollection<OrderItem> OrderItems即可。
内容的提问来源于stack exchange,提问作者filipe
相关产品推荐
相关产品推荐

