尝试将对象与EntityFramework关联时无效的列名称错误

时间:2014-06-27 14:58:48

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

实体框架给我带来了一些麻烦。

以下是我的表格:

产品

Products Table

相关产品

RelatedProducts Table

我的数据库环境(无论如何都是其中的一部分)......

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'."}

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

如果Product.RelatedProductsRelatedProduct.OwnerRelatedProduct.Product的反向导航属性,则必须告知EF。两者都是可能且有效的,EF不能自行决定。

带有数据注释的解决方案(假设OwnerRelatedProducts相反):

[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_IDProduct_ID。但是,这些列在您的表中不存在,因此您会收到错误。通常的解决方法是明确告诉EF您的外键属性是什么:

[ForeignKey("Owner")]
public int OwnerID { get; set; }

public virtual Product Owner { get; set; }

有了这个,实体框架会查找OwnerID列,而且一切都很好。 @Slauma无意中解决了Fluent API方法的根本问题,该方法明确声明了用于HasForeignKey的外键的属性。这是一种同样有效的方法,但我觉得你应该知道实际你的问题是什么。