我想了解MVC项目中的产品类别并使用它们来创建菜单。该模型驻留在WCF项目中,因此我按如下方式对其进行了实例化:
ServiceReference1.WSClient client = new ServiceReference1.WSClient();
我的产品型号是这样的:
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string ProductImagePath { get; set; }
public string Specifications { get; set; }
public string Options { get; set; }
public double? UnitPrice { get; set; }
public int? CategoryId { get; set; }
public Category Category { get; set; }
public int Stock { get; set; }
}
我的分类模型是这样的:
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public string Despcription { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
我想获得这样的产品类别:
public PartialViewResult Menu()
{
List<Product> products = client.GetAvailableProducts().ToList();
IEnumerable<string> categories = products
.Select(myproduct => myproduct.Category.CategoryName) // <- offending line
.Distinct()
.OrderBy(x => x);
return PartialView(categories);
}
方法GetAvailableProducts()有效,因为我得到了产品列表,所以我知道该服务正在运行。但是,在运行应用程序时,我在Linq查询中得到一个空引用异常(参见上面的违规行)。
在我看来,必须实例化类别,然后,如何构建LINQ查询以便实例化类别?任何人都可以指出如何做到这一点?
BR,
加布里埃尔
答案 0 :(得分:3)
在服务中序列化产品时,您应该使用LoadWith来序列化任何链接的实体。这是因为默认值是延迟加载,EF在访问之前不会加载链接的实体。序列化产品时,不会访问类别。 LoadWith
将执行急切加载,以便所有数据都会被序列化。
示例:
public IEnumerable<Product> GetAvailableProducts()
{
var ctx = new ProductsContext();
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Product>(p => p.Category);
ctx.LoadOptions = dlo;
return ctx.Products.ToList();
}
修改强>
猜猜下午太晚了。 :(
LoadWith
与Linq to SQL
结合使用
使用Entity Framework
,您应该使用Include代替:
public IEnumerable<Product> GetAvailableProducts()
{
var ctx = new ProductsContext();
return ctx.Products.Include("Category").ToList();
}
免责声明: 未经过测试的代码
答案 1 :(得分:2)
您正在成功提取产品,但您的服务并未拉下相关类别。
因此,当您执行myproduct.Category.CategoryName
时,Category
始终为null
。
您需要告诉服务返回相关类别。
答案 2 :(得分:1)
看起来你的关系是0或1到多,因为CategoryId是一个int?。如果Category为null,则您无法执行Category.CategoryName。这是一个空引用。
答案 3 :(得分:1)
在您的违规行myproduct.Category上,有一个或多个null类别。你需要改变
client.GetAvailableProducts().ToList();
还可以下拉每个产品组成的类别。
你也应该保护不可避免的空类别。