2016-05-27 3 views
0

多くの時間の調査の後に私が立ち往生しているので、私はこの問題について助けが必要です。エンティティフレームワーク6、多くの外部キーの同じ列

私はEntity Framework 6(私はコードファーストアプローチを使用しています)を使用して、既存の古いデータベースからデータモデルを作成しました。このデータベースはマルチ企業指向であるため、ほとんどのテーブルには、ほとんどすべての主キーと外部キーの一部として使用される「Company」という列があります。

データモデル作成では、Fluent APIを使用してすべての外部キーが作成されました。しかし、これは役に立たず、テーブルからデータを選択しようとすると「無効な列名 'TABLE_COLUMN'」というエラーが表示されます。このデータベースでは通常、列ごとに異なるテーブル名があり、Entityフレームワークは関係、その列名をマップするために必要な

だから、私はDataAnnotationsを使用して問題を解決することができ、私は例えば、行うことができますので:?今happends

 [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; } 

テーブルCOMPANY列も必要とする別の外部キーがあります。データアノテーション私は列を2回使用することを許可していません、私はテーブルを動作させることはできません。

データモデルで、2番目の外部キーの流暢なAPI定義を作成しましたが、機能しません。

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

実は私は「無効な列名のCABAJUSTES_CODAJUSTE」と「無効な列名のCABAJUSTES_COMPANY」のようなエラーを受信したデータを取得しようとそのこと毎回。そして、私はこの第二の外部キーをマップすることができません。

どうすればよいですか?

ありがとうございます。

答えて

1

テーブル構造に従うのが少し難しいので、私は、誰もが従うべき共通のエンティティを使って包括的な例を設定しようとしました。これがあなたの問題を十分に説明していない場合は、ご意見ください。私は故意をしました

は、Entity Frameworkの手助け自動マッピングは、私を助けていない、これはあなたが持つかもしれないレガシーデータベース設計で動作することを示すために確認するために、かなりくだらない外部キーを使用していました。例

  • 一つCompany

    まず予想される構造は、多くのArticle sおよび多くのInvoice Sを保持しています。

  • 1つのInvoiceが多くあります。InvoiceRowがあります。
  • 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を使用して2つの異なるファイルがあり、間違ったファイルを変更していたため、問題が発生していたことに気付きました。これに気づいた後、私は外部キーを適切に設定することができ、あなたの例も助けになりました。 – Anton

関連する問題