如何让EntityFramework检查2个参数?

我有3个相关对象(为简洁起见省略了非相关属性):

public class Product { public int ID { get; set; } public virtual ProductPrice Price { get; set; } } public class ProductPrice { public int ID { get; set; } public int ProductID { get; set; } public int VerticalID { get; set; } public decimal Value { get; set; } public virtual Product Product { get; set; } public virtual Vertical Vertical { get; set; } public override string ToString() { return Value.ToString("C"); } } public class Vertical { public int ID { get; set; } public string Name { get; set; } } 

产品价格根据当前的“垂直”而有所不同。 当前的垂直可能(最终)存储在会话中,但暂时,我们假设这将是一个查询字符串参数。 (例如mydomain.com?VerticalID=2 )。

我的问题

当用户访问mydomain.com/products?VerticalID=2mydomain.com/products/?VerticalID=2如何让entity framework根据ProductID VerticalID选择/分配正确的价格 – 使这成为可能? :

 @Model.Price.ToString() 

更新1(样本数据和数据库结构)

这是我的虚拟内容表:

制品

产品表

ProductPrices

ProductPrices表

垂直

垂直表

关系解释

每个垂直应该有一个价格,每个产品。 查询看起来像:

 -- Let's assume ProductID = 2 and VerticalID = 1 (eg mydomain.com/products/2?VerticalID=1) SELECT * FROM ProductPrices WHERE ProductID = 2 AND VerticalID = 1 

上面的查询将返回1行(这应该总是返回)


更新2(另一个例子)

为了便于说明,我将VerticalID属性添加到Product:

 public class Product { public int ID { get; set; } public string Manufacturer { get; set; } public string Model { get; set; } public string PartNumber { get; set; } public int CategoryID { get; set; } public string Description { get; set; } [NotMapped] public int VerticalID = 1; public virtual ProductCategory Category { get; set; } public virtual ProductPrice Price { get; set; } public virtual ICollection Images { get; set; } public virtual ICollection Documents { get; set; } public virtual ICollection Details { get; set; } public virtual ICollection RelatedProducts { get; set; } } 

现在,当实际尝试执行此操作时,我收到以下错误:

 Unable to determine the principal end of an association between the types 'Print_Solutions.Models.ProductPrice' and 'Print_Solutions.Models.Product'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations. 

如何在检索价格时告诉实体使用VerticalID和Product.ID? (使用我所拥有的测试数据,如果这是产品1,则该产品应映射到产品价格表的ID 1,并且成本为100美元)。

假设您的DbContext有一个名为ProductPricesProductPrice集合,使用LINQ您只需进行以下查询:

 var price = ctx.ProductPrices.Where(pp => pp.ProductId = productId && pp.VerticalId == verticalId).SingleOrDefault(); 

其中productIdverticalId是来自动作参数,会话或任何位置的可用参数。

使用单个或默认保证,即数据库上只有一个值,或者没有,并且在这种情况下,由于查询,您将获得null

至于您的更新,我发现您的问题也与模型中关系的定义有关。

有3种方法可以实现它:

  • 使用EF约定。 要实现此目的,请更改您的entites的ID属性的名称:例如,使用ProductId而不是ID ,约定将为您构建模型
  • 使用属性。 在这种特殊情况下,使用适用的ForeignKeyAttribute
  • 使用流畅的API

您可以在此处获得更多关于关系的信息 ,其中包含一些简单的示例。

我无法弄清楚如何修复模型或使用流畅的API。 我做了一些延迟加载。 如果有人有更好的解决方案,请发布。

 public class Product { public int ID { get; set; } public string Manufacturer { get; set; } public string Model { get; set; } public string PartNumber { get; set; } public int CategoryID { get; set; } public string Description { get; set; } public int VerticalID = 1; private ProductPrice _price; public virtual ProductCategory Category { get; set; } public virtual ICollection Images { get; set; } public virtual ICollection Documents { get; set; } public virtual ICollection Details { get; set; } public virtual ICollection RelatedProducts { get; set; } // Lazy Loading public ProductPrice Price { get { if (_price == null) { var db = new ApplicationContext(); _price = db.Prices.FirstOrDefault(p => p.ProductID == ID && p.VerticalID == VerticalID); } return _price; } } }