实体框架给我带来了一些麻烦。
以下是我的表格:
产品
相关产品
我的数据库环境(无论如何都是其中的一部分)......
ApplicationContext.cs
public class ApplicationContext : DbContext
{
public ApplicationContext() : base("DefaultConnection")
{
}
public DbSet<Product> Products { get; set; }
public DbSet<RelatedProduct> RelatedProducts { get; set; }
}
模特......
Product.cs
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 decimal Price { get; set; }
public virtual ICollection<RelatedProduct> RelatedProducts { get; set; }
}
RelatedProduct.cs
public class RelatedProduct
{
public int ID { get; set; }
public int OwnerID { get; set; }
public int ProductID { get; set; }
public virtual Product Owner { get; set; }
public virtual Product Product { get; set; }
}
循环浏览相关产品列表,如下所示:
<ul class="activity">
@foreach (var related in @Model.RelatedProducts)
{
<li>
<i class="fa fa-chevron-right red"></i> <strong>@related.Product.Manufacturer:</strong> @related.Product.Model
</li>
}
</ul>
我一直收到这个错误
{"Invalid column name 'Product_ID'.\r\nInvalid column name 'Product_ID'.\r\nInvalid column name 'Product_ID'."}
有什么想法吗?
答案 0 :(得分:3)
如果Product.RelatedProducts
是RelatedProduct.Owner
或RelatedProduct.Product
的反向导航属性,则必须告知EF。两者都是可能且有效的,EF不能自行决定。
带有数据注释的解决方案(假设Owner
与RelatedProducts
相反):
[InverseProperty("RelatedProducts")]
public virtual Product Owner { get; set; }
public virtual Product Product { get; set; }
或使用Fluent API:
modelBuilder.Entity<RelatedProduct>()
.HasRequired(r => r.Owner)
.WithMany(p => p.RelatedProducts)
.HasForeignKey(r => r.OwnerID);
modelBuilder.Entity<RelatedProduct>()
.HasRequired(r => r.Product)
.WithMany()
.HasForeignKey(r => r.ProductID)
.WillCascadeOnDelete(false);
可能只有Fluent API解决方案才有效,因为您还需要为其中一个与数据注释无关的关系禁用级联删除。
答案 1 :(得分:2)
实际上,这里的问题是实体框架的“约定优于配置”。外键列的约定在未明确添加为属性时,将其命名为[RelatedProperty]_[RelatedClassPK]
。在您的情况下Owner_ID
和Product_ID
。但是,这些列在您的表中不存在,因此您会收到错误。通常的解决方法是明确告诉EF您的外键属性是什么:
[ForeignKey("Owner")]
public int OwnerID { get; set; }
public virtual Product Owner { get; set; }
有了这个,实体框架会查找OwnerID
列,而且一切都很好。 @Slauma无意中解决了Fluent API方法的根本问题,该方法明确声明了用于HasForeignKey
的外键的属性。这是一种同样有效的方法,但我觉得你应该知道实际你的问题是什么。