2013-10-30 14 views
1

我有一个产品类:实体框架一到一个有一个是可选的关系抛出错误

public class Product 
{ 
    public int ID { get; set; } 

    [Required] 
    public string Name { get; set; } 
    public decimal Price { get; set; } 

    public Offer Offer { get; set; } 
} 

和报价类:

public class Offer 
{ 
    public int ID { get; set; } 

    [Required] 
    public DateTime DateFrom { get; set; } 
    public DateTime DateTo { get; set; } 
    public decimal OfferPrice { get; set; } 
    public Product Product { get; set; } 
} 

基本上想我要实现的是,当报价中添加了与此优惠相关的产品。因此,优惠总是有产品,但产品并不总是需要优惠。如果产品确实有一个我希望能够通过Product.Offer访问它,但在此设置,我得到更新数据库时出现以下错误信息:

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

我已经尝试了很多东西(数据注释和Fluent API)并且无休止地搜索,但我似乎无法解决此问题。我尝试过的流利的API方法:

modelBuilder.Entity<Offer>() 
      .HasRequired(x => x.Product) 
      .WithOptional(x => x.Offer); 

但是,这工作无济于事,我该如何分配一个Principal End?和什么课程?

回答

2

试试这个:

public class Product 
{ 
    public int ID { get; set; } 

    [Required] 
    public string Name { get; set; } 
    public decimal Price { get; set; } 

    public Offer Offer { get; set; } 
} 

public class Offer 
{ 
    [ForeignKey("Product")] 
    public int ID { get; set; } 

    [Required] 
    public DateTime DateFrom { get; set; } 
    public DateTime DateTo { get; set; } 
    public decimal OfferPrice { get; set; } 
    public Product Product { get; set; } 
} 
+1

感谢您的回复!这会引发以下错误:'''“错误:新名称'ID'已经被用作COLUMN名称,并且会导致不允许的重复。'''' – Mirage

+1

你可以尝试删除你的数据库然后更新数据库? – WannaCSharp

+0

我已经通过服务器资源管理器手动删除所有表,现在我似乎无法让我的表回来..我如何重置迁移历史,并让它创建一个基于我当前类的全新数据库? – Mirage

1

当你有一个一到一个关系,一个实体必须委托人和其他人必须是相关的。在这种情况下,我建议你,以确保产品编号是FK和PK的发售,通过使用数据anotations就像这样:

public class Product 
    { 
     public int ID { get; set; } 
     [Required] 
     public string Name { get; set; } 
     public decimal Price { get; set; } 
     public Offer Offer { get; set; } 
    } 

    public class Offer 
    { 
     public int ID { get; set; } 
     [Required] 
     public DateTime DateFrom { get; set; } 
     public DateTime DateTo { get; set; } 
     public decimal OfferPrice { get; set; } 
     [Required] 
     public Product Product { get; set; } 
    } 

在另一方面,你更了解你的项目,但我也会推荐你使用1:N关系。希望它的工作。

+0

Hey Guillelon,谢谢你的回复。我尝试了在你的答案中描述的变化,但是这导致了一个不同的错误:''错误:新名称'ID'已经被用作一个COLUMN名字,并且会导致不允许的副本。 ' – Mirage

+0

如果您使用的是代码优先迁移,请从数据库中删除包含名为“__MigrationHistory”的表,并删除项目中的所有迁移。然后再次创建迁移并运行update-database。 –

0

我对于一对多关系有类似的错误信息。 我忘记了在父属性上显式使用ForeignKey属性。 然后,当我尝试添加属性时,我得到了一个无法运行的迁移。 我能够通过编辑迁移来解决错误

public override void Up() 
{ 

    //DropIndex("dbo.PurchaseManifestLines", new[] { "PurchaseOrderLineId" }); 
    //RenameColumn(table: "dbo.PurchaseManifestLines", name: "PurchaseOrderLineId", newName: "PurchaseOrderLine_Id1"); 
    //AddColumn("dbo.PurchaseManifestLines", "PurchaseOrderLine_Id", c => c.Int(nullable: false)); 
    //AlterColumn("dbo.PurchaseManifestLines", "PurchaseOrderLine_Id1", c => c.Int()); 
    //CreateIndex("dbo.PurchaseManifestLines", "PurchaseOrderLine_Id1"); 
    // gives error Column names in each table must be unique. Column name 'PurchaseOrderLine_Id' in table 'dbo.PurchaseManifestLines' is specified more than once. 


    //replaced with 
    DropIndex("dbo.PurchaseManifestLines", new[] { "PurchaseOrderLineId" }); 
    DropColumn("dbo.PurchaseManifestLines", "PurchaseOrderLineId"); 

} 
+0

我也遇到了Code-First的情况,这是通过从代码中删除业务类,创建迁移来删除表并运行它,然后恢复业务对象代码并创建迁移以重新创建表来解决的。然后运行它。 –

相关问题