2016-03-03 101 views
0

我使用實體框架7 RC1和我有實體:INSERT語句衝突與外鍵約束「FK_PostTag_Tag_TagId」

public class Post { 
    public Int32 Id { get; set; } 
    public String Title { get; set; } 
    public virtual IList<PostTag> PostsTags { get; set; } 
} 

public class Tag { 
    public Int32 Id { get; set; } 
    public String Name { get; set; } 
    public virtual IList<PostTag> PostsTags { get; set; } 
} 

public class PostTag { 
    public Int32 PostId { get; set; } 
    public Int32 TagId { get; set; } 
    public virtual Post Post { get; set; } 
    public virtual Tag Tag { get; set; } 
} 

該機型配置了這些實體如下:

protected override void OnModelCreating(ModelBuilder builder) { 

    base.OnModelCreating(builder); 

    builder.Entity<Post>(b => { 

    b.ToTable("Posts"); 
    b.HasKey(x => x.Id); 
    b.Property(x => x.Id).UseSqlServerIdentityColumn(); 
    b.Property(x => x.Title).IsRequired().HasMaxLength(100); 
    }); 

    builder.Entity<Tag>(b => { 
    b.ToTable("Tags"); 
    b.HasKey(x => x.Id); 
    b.Property(x => x.Id).UseSqlServerIdentityColumn(); 
    b.Property(x => x.Name).IsRequired().HasMaxLength(100); 
    }); 

    builder.Entity<PostTag>(b => { 
    b.ToTable("PostsTags"); 
    b.HasKey(x => new { x.PostId, x.TagId }); 
    b.HasOne(x => x.Post).WithMany(x => x.PostsTags).HasForeignKey(x => x.PostId); 
    b.HasOne(x => x.Tag).WithMany(x => x.PostsTags).HasForeignKey(x => x.TagId); 
    }); 

} 

我創建了遷移和數據庫。然後我試圖創建一個帖子:

Context context = new Context(); 

    Post post = new Post { 
    PostsTags = new List<PostTag> { 
     new PostTag { 
     Tag = new Tag { Name = "Tag name" } 
     } 
    }, 
    Title = "Post title" 
    }; 

    context.Posts.Add(post); 

    await _context.SaveChangesAsync(); 

而且在保存我得到以下錯誤:

An error occurred while updating the entries. 
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_PostTag_Tag_TagId". 
The conflict occurred in database "TestDb", table "dbo.Tags", column 'Id'. 
The statement has been terminated. 

有誰知道這個錯誤的原因是什麼?

回答

0

我會說你不需要在EF CodeFirst中明確聲明你的外鍵,框架會爲你處理它。因此,從PostTag類

public Int32 PostId { get; set; } 
public Int32 TagId { get; set; } 

刪除這些屬性,然後從你的配置這兩條線,然後再次嘗試保存。您可能需要在保存之前更新您的數據庫模型。

b.HasKey(x => new { x.PostId, x.TagId }); 
b.HasOne(x => x.Post).WithMany(x => x.PostsTags).HasForeignKey(x => x.PostId); 
b.HasOne(x => x.Tag).WithMany(x => x.PostsTags).HasForeignKey(x => x.TagId); 
+0

但是我想在我的模型上使用FK ...我總是有幾個查詢它是真的有用...順便說一句,我從來沒有與EF 6這個問題... –

+0

在這種情況下,你有使您的外鍵可以爲空。在你的例子中,你的PostId將爲0,這是打破FK約束,因爲我猜你沒有0作爲DB中的PostId。 –

+0

我得到了同樣的錯誤,甚至使兩個鍵可空... –

1

我有同樣的問題。這是我提出的解決方案。 This這個問題幫了我很多。

首先,如果缺失,請將public DbSet<Tag> Tags {get; set;}添加到您的Context類中。

然後修改後創建以下

Context context = new Context(); 
var tmpTag = new Tag { Name = "Tag name" } //add the tag to the context 
context.Tags.Add(tmpTag); 

Post post = new Post { 
    PostsTags = new List<PostTag>(), // initialize the PostTag list 
    Title = "Post title" 
};  
context.Posts.Add(post); 

var postTag = new PostTag() {Post = post, Tag = tag}; // explicitly initialize the PostTag AFTER addig both Post and Tag to context 
post.PostTags.Add(postTag); // add PostTag to Post 

await _context.SaveChangesAsync(); 

嘗試創建PostTag對象之前顯式地將兩者posttagcontext.Postscontext.Tags允許EF正確管理的ID而寫入底層數據庫。

爲了完整起見,在解決了多對多關係管理的這一部分之後,我目前正在使用CascadeDelete Entity Framework Core(EF7),但這是一個不同的故事。

+0

我們仍然需要解決這個問題*發佈候選*。 EF應該能夠確定插入順序本身。 –

相關問題