创建一个LINQ查询,从两个实体中获取数据

时间:2014-06-10 14:05:44

标签: c# asp.net-mvc linq entity-framework wcf

我想了解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,

加布里埃尔

4 个答案:

答案 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();
}

修改

猜猜下午太晚了。 :(

LoadWithLinq 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();

还可以下拉每个产品组成的类别。

你也应该保护不可避免的空类别。