2016-05-27 39 views
0

我需要关于这个问题的帮助,因为经过很多小时的调查后,我被卡住了。实体框架6,许多外键的相同列

我使用Entity Framework 6(我使用Code First方法)从现有的旧数据库创建了一个数据模型。这个数据库是以多公司为导向的,所以它的大多数表格都有一个“公司”列,它用作几乎所有主键和外键的一部分。

数据模型创建使用Fluent API创建所有外键。但是这并没有帮助,当我尝试从任何表中选择数据时,我收到了错误“无效的柱状图名称'TABLE_COLUMN'。因为在这个数据库中通常每个表中的列有不同的名称,并且实体框架无法确定关系,所以它需要映射的列名

所以,我可以使用DataAnnotations解决这个问题,我可以做,比如:?

 [Key] 
    [Column(Order = 1)] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    [ForeignKey("BLOQHOR"), InverseProperty("CODHOR")] 
    public int NUMHOR { get; set; } 

    [Key] 
    [Column(Order = 2)] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    [ForeignKey("BLOQHOR"), InverseProperty("DISTAINIC")] 
    public int DISTAINIC { get; set; } 

    [Key] 
    [Column(Order = 3)] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    [ForeignKey("BLOQHOR"), InverseProperty("COMPANY")] 
    public int COMPANY{ get; set; } 

现在什么happends

表有另一个外键也需要列COMPANY。由于数据附注ons不允许我使用列两次,我不能让桌子工作。

我重复一遍,在数据模型中,它为第二个外键创建了流畅的api定义,但它不起作用。

  modelBuilder.Entity<CABAJUSTES>() 
      .HasMany(e => e.AJUSBLOQ) 
      .WithRequired(e => e.CABAJUSTES) 
      .HasForeignKey(e => new { e.NUMAJUST, e.COMPANY}) 

事实上它是每次我试图让我收到错误,如“无效的列名CABAJUSTES_CODAJUSTE”和“无效的列名CABAJUSTES_COMPANY”数据。而且我无法映射这第二个外键。

我该怎么办?

在此先感谢。

回答

1

它有点难以遵循你的表格结构,所以我试图设置一个全面的例子,使用任何人都应该能够遵循的共同实体。请评论,如果这不能完全描述你的问题。

注意,我已经故意使用非常低劣的外键,以确保在实体框架的帮助自动映射并不能帮助我,并表明这适用于任何传统的数据库设计你可能有。

首先在示例

  • 一个Company预期结构拥有许多Article S和许多Invoice秒。
  • 其中一个Invoice持有许多InvoiceRow s。
  • 每个InvoiceRow可以可选地指代Article

实际的实体

class Company 
{ 
    public int TheCompanyKey { get; set; } 

    public virtual ICollection<Invoice> Its_Invoices { get; set; } 
    public virtual ICollection<Article> Its_Articles { get; set; } 
} 

class Invoice 
{ 
    public int Its_CompanyKey { get; set; } 
    public int TheInvoiceKey { get; set; } 

    public string InvoiceNumber { get; set; } 
    public DateTime InvoiceDate { get; set; } 

    public virtual Company Its_Company { get; set; } 
    public virtual ICollection<InvoiceRow> Its_Rows { get; set; } 
} 

class InvoiceRow 
{ 
    public int Rows_Company_Key { get; set; } 
    public int Its_InvoiceID { get; set; } 
    public int RowNumber { get; set; } 

    public int? Its_Articles_ID { get; set; } 
    public string Text { get; set; } 
    public double Price { get; set; } 

    public virtual Invoice Its_Invoice { get; set; } 
    public virtual Article Its_Article { get; set; } 
} 

class Article 
{ 
    public int TheArticleCompany_Key { get; set; } 
    public int TheArticleKey { get; set; } 

    public string ArticleNumber { get; set; } 
    public double Cost { get; set; } 
    public double TargetPrice { get; set; } 

    public virtual Company Its_Company { get; set; } 
} 

与OnModelCreating的的DbContext()

有多种方式来生成所需的结构,这取决于如果你认为自上而下或自下而上。我对模型的理解是从基础表开始,并描述儿童与他们的关系。

class MyContext : DbContext 
{ 
    public MyContext() : base("name=MyContext") 
    { 
    } 

    public virtual IDbSet<Company> Companies { get; set; } 
    public virtual IDbSet<Invoice> Invoices { get; set; } 
    public virtual IDbSet<InvoiceRow> InvoiceRows { get; set;} 
    public virtual IDbSet<Article> Articles { get; set; } 


    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Company>() 
      .HasKey(e => e.TheCompanyKey); 

     modelBuilder.Entity<Article>() 
      .HasKey(e => new { e.TheArticleCompany_Key, e.TheArticleKey }) 
      .HasRequired(e => e.Its_Company).WithMany(e => e.Its_Articles).HasForeignKey(e => e.TheArticleCompany_Key); 

     modelBuilder.Entity<Invoice>() 
      .HasKey(e => new { e.Its_CompanyKey, e.TheInvoiceKey }) 
      .HasRequired(e => e.Its_Company).WithMany(e => e.Its_Invoices).HasForeignKey(e => e.Its_CompanyKey); 

     modelBuilder.Entity<InvoiceRow>() 
      .HasKey(e => new { e.Rows_Company_Key, e.Its_InvoiceID, e.RowNumber }); 

     modelBuilder.Entity<InvoiceRow>() 
      .HasRequired(e => e.Its_Invoice).WithMany(e => e.Its_Rows) 
      .HasForeignKey(e => new { e.Rows_Company_Key, e.Its_InvoiceID }).WillCascadeOnDelete(); 

     modelBuilder.Entity<InvoiceRow>() 
      .HasOptional(e => e.Its_Article) 
      .WithMany() 
      .HasForeignKey(e => new { e.Rows_Company_Key, e.Its_Articles_ID }); 
    } 
} 

最后生成的迁移

在以下迁移Package Manager Console窗口结果运行add-migration multikeys

public partial class multikeys : DbMigration 
{ 
    public override void Up() 
    { 
     CreateTable(
      "dbo.Articles", 
      c => new 
       { 
        TheArticleCompany_Key = c.Int(nullable: false), 
        TheArticleKey = c.Int(nullable: false), 
        ArticleNumber = c.String(), 
        Cost = c.Double(nullable: false), 
        TargetPrice = c.Double(nullable: false), 
       }) 
      .PrimaryKey(t => new { t.TheArticleCompany_Key, t.TheArticleKey }) 
      .ForeignKey("dbo.Companies", t => t.TheArticleCompany_Key, cascadeDelete: true) 
      .Index(t => t.TheArticleCompany_Key); 

     CreateTable(
      "dbo.Companies", 
      c => new 
       { 
        TheCompanyKey = c.Int(nullable: false, identity: true), 
       }) 
      .PrimaryKey(t => t.TheCompanyKey); 

     CreateTable(
      "dbo.Invoices", 
      c => new 
       { 
        Its_CompanyKey = c.Int(nullable: false), 
        TheInvoiceKey = c.Int(nullable: false), 
        InvoiceNumber = c.String(), 
        InvoiceDate = c.DateTime(nullable: false), 
       }) 
      .PrimaryKey(t => new { t.Its_CompanyKey, t.TheInvoiceKey }) 
      .ForeignKey("dbo.Companies", t => t.Its_CompanyKey, cascadeDelete: true) 
      .Index(t => t.Its_CompanyKey); 

     CreateTable(
      "dbo.InvoiceRows", 
      c => new 
       { 
        Rows_Company_Key = c.Int(nullable: false), 
        Its_InvoiceID = c.Int(nullable: false), 
        RowNumber = c.Int(nullable: false), 
        Its_Articles_ID = c.Int(), 
        Text = c.String(), 
        Price = c.Double(nullable: false), 
       }) 
      .PrimaryKey(t => new { t.Rows_Company_Key, t.Its_InvoiceID, t.RowNumber }) 
      .ForeignKey("dbo.Articles", t => new { t.Rows_Company_Key, t.Its_Articles_ID }) 
      .ForeignKey("dbo.Invoices", t => new { t.Rows_Company_Key, t.Its_InvoiceID }, cascadeDelete: true) 
      .Index(t => new { t.Rows_Company_Key, t.Its_Articles_ID }) 
      .Index(t => new { t.Rows_Company_Key, t.Its_InvoiceID }); 

    } 

    public override void Down() 
    { 
     DropForeignKey("dbo.Articles", "TheArticleCompany_Key", "dbo.Companies"); 
     DropForeignKey("dbo.InvoiceRows", new[] { "Rows_Company_Key", "Its_InvoiceID" }, "dbo.Invoices"); 
     DropForeignKey("dbo.InvoiceRows", new[] { "Rows_Company_Key", "Its_Articles_ID" }, "dbo.Articles"); 
     DropForeignKey("dbo.Invoices", "Its_CompanyKey", "dbo.Companies"); 
     DropIndex("dbo.InvoiceRows", new[] { "Rows_Company_Key", "Its_InvoiceID" }); 
     DropIndex("dbo.InvoiceRows", new[] { "Rows_Company_Key", "Its_Articles_ID" }); 
     DropIndex("dbo.Invoices", new[] { "Its_CompanyKey" }); 
     DropIndex("dbo.Articles", new[] { "TheArticleCompany_Key" }); 
     DropTable("dbo.InvoiceRows"); 
     DropTable("dbo.Invoices"); 
     DropTable("dbo.Companies"); 
     DropTable("dbo.Articles"); 
    } 
} 

摘要

我认为这说明了OP的问题,一点点研究可以很好地理解Fluent如何用于映射实体。

祝你好运!

+0

谢谢你的帮助。最后我注意到这个问题发生了,因为我有两个不同的流利API文件,我正在修改不正确的文件。在注意到这一点之后,我能够正确配置外键,并且您的示例也得到了帮助。 – Anton