1

私は、比較的シンプルな関係マッピング(1対多)であると思っていたものを理解しようとしました。EF 6関係:モデル生成中に1つまたは複数の検証エラーが検出されました

のは、私がモデルに持っているものの上に行こう:

ContentExternalLinkマッピングに今

public class ContentExternalLink 
{ 
    public ContentExternalLink() 
    { 
     ContentTagAssignments = new List<ContentTagAssignment>(); 
    } 

    [Key] 
    public string LinkId { get; set; } 
    public string LinkTypeId { get; set; } 
    public string LinkTitle { get; set; } 
    public string LinkUrl { get; set; } 
    public string LinkSource { get; set; } 
    public string LinkPhoneNumber { get; set; } 
    public DateTime LinkDate { get; set; } 
    public DateTime LinkCreatedDate { get; set; } 
    public DateTime LinkModifiedDate { get; set; } 
    [ScriptIgnore] 
    public virtual ICollection<ContentTagAssignment> ContentTagAssignments { get; set; } 
} 

ContentTagAssignmnent

public class ContentTagAssignment 
{ 
    public ContentTagAssignment() 
    { 
     this.ContentExternalLink = new ContentExternalLink(); 
    } 

    [Key] 
    public string TagId { get; set; } 
    [Key] 
    public string ArticleId { get; set; } 
    public bool IsPrimary { get; set; } 
    public DateTime CreatedDate { get; set; } 
    [ScriptIgnore] 
    public virtual ContentExternalLink ContentExternalLink { get; set; } 
} 

ContentExternalLinkMap

public class ContentExternalLinkMap : EntityTypeConfiguration<ContentExternalLink> 
{ 
    public ContentExternalLinkMap() 
    { 
     this.ToTable("content_external_link", "dbo"); 

     this.HasKey(c => c.LinkId); 

     this.Property(c => c.LinkId).HasColumnName("link_id"); 
     this.Property(c => c.LinkTypeId).HasColumnName("link_type_id"); 
     this.Property(c => c.LinkTitle).HasColumnName("link_title"); 
     this.Property(c => c.LinkUrl).HasColumnName("link_url"); 
     this.Property(c => c.LinkSource).HasColumnName("link_source"); 
     this.Property(c => c.LinkPhoneNumber).HasColumnName("link_phone_number"); 
     this.Property(c => c.LinkDate).HasColumnName("link_date"); 
     this.Property(c => c.LinkCreatedDate).HasColumnName("link_created_date"); 
     this.Property(c => c.LinkModifiedDate).HasColumnName("link_modified_date"); 
    } 
} 

ContentTagAssignmnetMap

public class ContentTagAssignmentMap : EntityTypeConfiguration<ContentTagAssignment> 
{ 
    public ContentTagAssignmentMap() 
    { 
     this.ToTable("content_tag_assignment", "dbo"); 

     this.HasKey(t => new {t.TagId, t.ArticleId}); 

     this.Property(t => t.TagId).HasColumnName("tag_id"); 
     this.Property(t => t.ArticleId).HasColumnName("article_id"); 
     this.Property(t => t.IsPrimary).HasColumnName("is_primary_tag"); 
     this.Property(t => t.CreatedDate).HasColumnName("created_date"); 


     this.HasOptional(t => t.ContentExternalLink) 
      .WithMany(t => t.ContentTagAssignments) 
      .HasForeignKey(t => new {t.TagId, t.ArticleId}); 
    } 
} 

ContentTagAssignmentにおける情報でarticleIDと一致しますがLinkIdのような関係は奇妙側に間違いです。

私はContentTagAssignmentMapに次のように試してみた:

//this.HasOptional(t => t.ContentExternalLink) 
// .WithMany(t => t.ContentTagAssignments) 
// .HasForeignKey(t => t.ContentExternalLink); 

this.HasOptional(x => x.ContentExternalLink) 
    .WithMany(x=>x.ContentTagAssignments) 
    .Map(x => x.MapKey("LinkId").HasColumnAnnotation("LinkId","ArticleId",null)); 

//this.Map(m => 
// { 
//  m.Properties(x => x.ArticleId); 
//  m.ToTable("content_tag_assignment"); 
// }) 
// .Map(p => 
// { 
//  p.Properties(x => x.ContentExternalLink.LinkId); 
//  p.ToTable("ContentExternalLink"); 
// }); 

コメント関係は動作しません。動作するもの(初期ページの読み込みに失敗しないという点で)。ただし、ContentExternalLinkからリストにアクセスしようとすると、次のエラーが表示されます。{"無効な列名 'LinkId'。\ r \ n無効な列名 'LinkId'。"}

失われた...

質問

基本的には、必ずしもすべてのContentExternalLinkは、それにタグが割り当てられています。しかし、ContentExternalLinkにContentTagAssignmentsがある場合は、それらのリストを取得できるはずです。また、TagIdとArticleIdは文字列(guid)です。

誰にも提案はありますか?

ありがとうございました!

+0

あなたが示された両方のモデルが( 'ContentTagAssignmnent')と同じです:) –

+0

@StephenMuecke DOH!私に教えてくれてありがとう、ContentExternalLinkモデルを実際のモデルで更新しました。 – ajtatum

+0

http://stackoverflow.com/q/20757594/861716 –

答えて

2

ivan stoevからのコメントの後、私は外部キーが主キーであるとき、ここでユニークな間違いがオプション設定されていることを確認(not nullable

だからマッピングは次のようになります。以下は

public class ContentTagAssignmentMap : EntityTypeConfiguration<ContentTagAssignment> 
{ 
    public ContentTagAssignmentMap() 
    { 
     this.ToTable("content_tag_assignment", "dbo"); 

     this.HasKey(t => new { t.TagId, t.ArticleId }); 

     this.Property(t => t.TagId).HasColumnName("tag_id"); 
     this.Property(t => t.ArticleId).HasColumnName("article_id"); 
     this.Property(t => t.IsPrimary).HasColumnName("is_primary_tag"); 
     this.Property(t => t.CreatedDate).HasColumnName("created_date"); 


     this.HasRequired(t => t.ContentExternalLink) 
      .WithMany(t => t.ContentTagAssignments) 
      .HasForeignKey(t => t.ArticleId) 
      .WillCascadeOnDelete(false); 
    } 
} 

お使いのモデルで作業例です。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var ctx = new Context(); 
     ctx.Database.Delete(); 
     ctx.Database.CreateIfNotExists(); 

     Console.ReadKey(); 
    } 
} 

public class Context : DbContext 
{ 
    public Context():base ("Teste") 
    { 

    } 

    public DbSet<ContentExternalLink> ContentExternalLinks { get; set; } 
    public DbSet<ContentTagAssignment> ContentTagAssignments { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new ContentExternalLinkMap()); 
     modelBuilder.Configurations.Add(new ContentTagAssignmentMap()); 

     base.OnModelCreating(modelBuilder); 
    } 

} 

public class ContentExternalLink 
{ 
    public ContentExternalLink() 
    { 
     ContentTagAssignments = new List<ContentTagAssignment>(); 
    } 

    [Key] 
    public string LinkId { get; set; } 
    public string LinkTypeId { get; set; } 
    public string LinkTitle { get; set; } 
    public string LinkUrl { get; set; } 
    public string LinkSource { get; set; } 
    public string LinkPhoneNumber { get; set; } 
    public DateTime LinkDate { get; set; } 
    public DateTime LinkCreatedDate { get; set; } 
    public DateTime LinkModifiedDate { get; set; } 

    public virtual ICollection<ContentTagAssignment> ContentTagAssignments { get; set; } 
} 

public class ContentTagAssignment 
{ 
    public ContentTagAssignment() 
    { 
     this.ContentExternalLink = new ContentExternalLink(); 
    } 

    [Key] 
    public string TagId { get; set; } 
    [Key] 
    public string ArticleId { get; set; } 
    public bool IsPrimary { get; set; } 
    public DateTime CreatedDate { get; set; } 

    public virtual ContentExternalLink ContentExternalLink { get; set; } 
} 

public class ContentExternalLinkMap : EntityTypeConfiguration<ContentExternalLink> 
{ 
    public ContentExternalLinkMap() 
    { 
     this.ToTable("content_external_link", "dbo"); 

     this.HasKey(c => c.LinkId); 

     this.Property(c => c.LinkId).HasColumnName("link_id"); 
     this.Property(c => c.LinkTypeId).HasColumnName("link_type_id"); 
     this.Property(c => c.LinkTitle).HasColumnName("link_title"); 
     this.Property(c => c.LinkUrl).HasColumnName("link_url"); 
     this.Property(c => c.LinkSource).HasColumnName("link_source"); 
     this.Property(c => c.LinkPhoneNumber).HasColumnName("link_phone_number"); 
     this.Property(c => c.LinkDate).HasColumnName("link_date"); 
     this.Property(c => c.LinkCreatedDate).HasColumnName("link_created_date"); 
     this.Property(c => c.LinkModifiedDate).HasColumnName("link_modified_date"); 
    } 
} 

public class ContentTagAssignmentMap : EntityTypeConfiguration<ContentTagAssignment> 
{ 
    public ContentTagAssignmentMap() 
    { 
     this.ToTable("content_tag_assignment", "dbo"); 

     this.HasKey(t => new { t.TagId, t.ArticleId }); 

     this.Property(t => t.TagId).HasColumnName("tag_id"); 
     this.Property(t => t.ArticleId).HasColumnName("article_id"); 
     this.Property(t => t.IsPrimary).HasColumnName("is_primary_tag"); 
     this.Property(t => t.CreatedDate).HasColumnName("created_date"); 


     this.HasRequired(t => t.ContentExternalLink) 
      .WithMany(t => t.ContentTagAssignments) 
      .HasForeignKey(t => t.ArticleId) 
      .WillCascadeOnDelete(false); 
    } 
} 
ここ

は、上記のコードからの結果であります

Created Tables

+0

申し訳ありませんが、私は提案された変更を元に戻しました。FKは常に 'many'側にあるので、' LinkId'にすることはできません。 –

+0

あなたが使用する多くの面を参照するオプションの側面のキーです。 ContentExternalLinkを参照するContentTagAssignmentにFKが必要です。これはLinkId –

+1

です。しかし、OP提供の 'ContentTagAssignment'エンティティには' LinkId'プロパティはなく、OPの説明によれば、* LinkIdはContentTagAssignment *のArticleIdと一致するので、私の前提はそのステートメントに基づいています(そして、 )。 –

1

エンティティモデル/実装には2つの問題があります。

simlpler(Gert Arnold's commentに記載)から始めましょう。経験則として、コンストラクタ(または内部的に他の場所)内の単一のナビゲーションプロパティを決して初期化するべきではありません。これはEF遅延読み込み動作を壊すためです。

まもなく、単にContentTagAssignmentクラスのコンストラクタから

this.ContentExternalLink = new ContentExternalLink();

行を削除します。

ここでは主な問題です。 EF6は、主要エンドのPK(主キー)を参照するFK(外部キー)関係のみをサポートします。つまり、ContentTagAssignmentエンティティのコンポジットキー(TagId, ArticleId)を使用して、HasForeignKey(t => new {t.TagId, t.ArticleId})コールを設定しようとしているときに、ContentExternalLinkエンティティの単一のPK(LinkId)を参照することはできません。これらの2つの列が従属エンド(ContentTagAssignment)のPKを形成しているという事実は、関係には関係ありません。他の選択肢はありません.2つのフィールドのいずれかを選択する必要があります。 によると、LinkIdはContentTagAssignmentのArticleIdと一致します。これはArticleIdフィールドである必要があります。

私の推測が正しければ

、単に問題を解決する必要があります(コンストラクタ修正と一緒に)

this.HasRequired(t => t.ContentExternalLink) 
    .WithMany(t => t.ContentTagAssignments) 
    .HasForeignKey(t => t.ArticleId); 

とそれに

this.HasOptional(t => t.ContentExternalLink) 
    .WithMany(t => t.ContentTagAssignments) 
    .HasForeignKey(t => new {t.TagId, t.ArticleId}); 

を交換してください。 ArticleIdフィールドが故に、とにかくnull値を許容しないであろう、PKの一部であるので、私はまたHasRequiredHasOptionalを変更

注意。

0

正しい結合を示すことなく外部キーを取得しようとしていることが問題だと思います。あなたがする必要がどのような

は、使用する必要があり、実際の外部キーであるContentTagAssignmentにがLinkIdフィールドを追加し、それに参加している:

this.HasOptional(t => t.ContentExternalLink) 
.WithMany(t => t.ContentTagAssignments) 
.HasForeignKey(t => t.LinkId); 

理由は、あなたが探しに行くためにそれを言っているということですkey(tagId、ArticleId)はContentExternalLinkには存在しません。

関連する問題